データの正確性と一貫性の問題は、小さな不便から大きな企業を揺るがす問題にまで発展する可能性があります。データベース内のデータを安全に保存、変更、消去するコードを構築することは、非常に重要です。
そこで、Laravelのトランザクション処理の登場です。
トランザクション処理は、データの整合性を確保するのに便利なアプローチです。Laravelを使えば、さまざまなデータベースでこのトランザクション処理をシンプルに実行できます。
では、トランザクション処理とは?Laravelで実際にどのように使うことができるのでしょうか?
この記事を読み終える頃には、Laravelのトランザクション処理の概要と、プロジェクトでの効果的な使用方法を習得できているはずです。
Laravelのトランザクション処理とは
技術的な側面に進む前に、まずLaravelの(データベースを扱う)トランザクション処理がどんなものであるか、そしてどのようにその恩恵を受けることができるかを理解しましょう。
トランザクション処理は、アプリケーションのデータベース構造内で安全に実行できる操作で、具体的には、データを修正するSQLクエリなど(更新、削除、挿入など)が挙げられます。
どの時点でも、トランザクションのすべてのクエリをロールバックすることができます。さらに、実行したクエリは、データベースによって1つのアクションとして扱われます。
この例を見てみましょう。
アカウントを作成することができるアプリがあるとします。各アカウントには1人または多数のユーザーが紐付けられる可能性があります。アカウントと最初のユーザーの作成時、アカウントが正しく生成されたものの、ユーザーの方がうまくいかなかった場合、対処が必要になります。
このサンプルコードをご覧下さい。
// Create Account
$newAcct = Account::create([
'accountname' => Input::get('accountname'),
]);
// Create User
$newUser = User::create([
'username' => Input::get('username'),
'account_id' => $newAcct->id,
]);
ここには2つのシナリオがあり、厄介な問題が発生する可能性があります。
- アカウントが生成されない
- ユーザーの作成に失敗する
後者の状況について考えてみましょう。
利用可能なユーザーがいないアカウントを作成すると、データベースのデータ不整合につながります。これを解決するためには、いくつかの方法が考えられます。コーディングで回避するという、気の遠くなるような作業もありますし、コードを削除していくことも、または、トランザクション処理で対処することもできます。
トランザクション処理は、ほとんどのSQLデータベースに存在しますが、主にその実装と効率に違いがあります。MySQL、SQLite、PostgreSQL、Oracleなどの人気のシステムがトランザクション処理をサポートしているので、好みに応じたSQLデータベースの展開に困ることはないでしょう。
マイグレーション
マイグレーションは、Laravelの重要な要素で、データベース内にテーブルを構築し、修正を加え、アプリケーションのデータベーススキーマを共有することができます。Laravelのマイグレーションを使用すると、新しいカラムを追加したり、既存のカラムを削除したりして、テーブルを編集できます。
チームとアイデアを議論し、テーブル調整の必要性が生じたとします。そんな時には、チームの誰かが、SQLファイルを共有、インポートする必要があります。SQLファイルをインポートし忘れると、アプリケーションの動作に問題が発生する可能性があります。
そこで、Laravelのマイグレーションが活躍します。データベースに新しいカラムを追加したり、既にあるカラムに影響を与えることなくエントリーを削除したりすることができます。
シーダー(Seeder)
Laravelの開発者向けの機能に、シーダーというものがあります。これを使うと、様々なデータ型のテスト、バグの修正、パフォーマンスのチューニングが容易になります。1つのコマンドで、データベースシーダーを経由して、データベーステーブルに複数行のダミーデータを追加することができます。
その結果、データベース復元のたびに一つ一つの情報を入力することなく、新しいデータベースとサンプル値を使って作業を繰り返すことができます。
Laravelのトランザクション処理のオプション
Laravelでは、Adminerなどの様々なデータ管理ツールが利用できます。トランザクション処理については、データベース側に3つのメソッドがあり、手動でトランザクションを開始し、事細かに制御可能です。
多くのケースで、トランザクションをコミットまたはロールバックするタイミングを正確に定義するために、この手法が好まれています。
- トランザクションを開始:
DB::beginTransaction();
コマンドを使用してトランザクションを開始します。 - トランザクションをロールバック:変更または操作を取り消す場合は、
DB::rollBack();
コマンドを使用します。 - トランザクションをコミット:すべてが計画通りに進んだ場合、
DB::commit();
コマンドを使用します。
トランザクションはすべて、コミットまたはロールバックのどちらかのアクションで終了させる点をお忘れ無く(特にループで重要)。そうしないと、同期がとれず、レコードが更新されなくなります。
Laravelデータベースとの連携
マイグレーションとシーダーは、前述したように、Laravel開発者向けの洗練されたソリューションで、アプリケーションのデータベースを迅速にデプロイ、削除、リストアすることができます。特に、複数の開発者が同じアプリで作業している場合に便利です。
このセクションでは、artisanコマンドを使用して、Laravelデータベースで簡単にマイグレーションとシーダーを使用する方法をご紹介します。
前提条件
必要なものは以下のとおりです。
- Ubuntu 18.04のローカルコンピュータまたは開発サーバーで、sudo権限を持つ非rootユーザー。リモートサーバーを使用している場合は、有効なファイアウォールを設定しておくのが得策です。
- マシンにLEMPがインストールされていること。DockerとDocker Composeをインストールすることで、より快適にアプリケーションを実行することができます。
ちなみに、Kinstaが開発したオリジナルソフトウェアであるDevKinstaではDockerが採用されており、現在、36,150+を超える開発者やデザイナーの方々に、WordPressサイト作成や開発にご活用いただいています。
もちろん、スキルやコーディングの要件に応じて、他にもウェブ開発ツールはたくさんありますので、お好みのものをお使いください。
Laravelのマイグレーション
マイグレーションクラスには、upとdownの2つのメソッドがあります。upメソッドは、データベースに新しいテーブル、インデックス、またはカラムを作成するのに使用します。ダウンメソッドは、アップメソッドによる操作を元に戻すために使われます。
Laravelのスキーマビルダを使用して、それぞれのメソッドで自由にテーブルを構築、編集することができます。例えば、このマイグレーションでは、フライトのテーブルを生成しています。
use IlluminateDatabaseMigrationsMigration;
use IlluminateDatabaseSchemaBlueprint;
use IlluminateSupportFacadesSchema;
class CreateFlightsTable extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up() {
Schema::create('flights', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->string('airline');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down() {
Schema::drop('flights');
}
make:migration
コマンドでは、テーブルの名前を明確にする必要があります。そのため、table_name
が希望するものと一致するようにしてください。
runメソッドのコード内で依存関係をタイプヒントしたい場合は、Laravelサービスコンテナが自動的に解決してくれます。
さらに、call
関数を使用すると、このクラスから別のシードクラスを実行することができ、シードの順序のカスタマイズが可能になります。データベースのシーディングを複数ファイルに分割し、特定のシーダークラスが過剰に拡張しないようにすることができます。
以下のように、使用したいシーダークラスの名前を入力します。
/**
* Run the database seeds.
*
* @return void
*/
public function run() {
$this->call([
UsersTableSeeder::class,
PostsTableSeeder::class,
CommentsTableSeeder::class,
]);
}
シーダーの実行
シーダーを生成した後、場合によっては、dump-autoload
コマンドを使用してComposerのオートローダを再作成する必要があるかもしれません。
composer dump-autoload
次に、db:seed
artisanコマンドを実行して、データベースのシードを作成します。
php artisan db:seed
このコマンドは、DatabaseSeeder
クラスをプロキシで実行するもので、他のシーダークラスを実行するために使用することができます。ただし、次のように--class
パラメータを使用して、特定のシーダークラスを個別に実行することも可能です。
php artisan db:seed --class=UserTableSeeder
すべてのテーブルを削除し、すべてのマイグレーションをもう一度実行するなど、データベースをゼロから作り直したい場合はこちら。migrate:fresh
コマンドを使用して、データベースのシーディングを行います。
php artisan migrate:fresh --seed
マイグレーションと同様に、シード処理によってはデータの損失や不要な変更が発生する可能性があります。このため、プライマリデータベースでシーディングコマンドを実行しないようにするため、シーディングを実行する前に承認を求めるプロンプトが表示されます。
十分な自信があり、この保護策を邪魔に感じる場合には、以下の--force
フラグを使用してください。
php artisan db:seed --force
Laravelで生のデータベースクエリを使用する(その他の5つの方法)
LaravelにはEloquentやQuery Builderなどの便利なツールがありますが、SQLを使用して生のクエリを実行することもできます。5つの方法をご紹介します。
ここで一点、注意事項があります。生のクエリは自動で保護されませんので、リスクの高いアプローチであることをお忘れ無く。したがって、クエリに何らかのパラメータを与える場合は、テキストではなく数値など、正しい形式と正しい値であることを確認する必要があります。
結果なしでクエリを実行する
DB::statement
では、SQLクエリを実行し、結果が無しということもあり得ます。例えば、INSERT
やUPDATE
などです(変数なし)。
これは、データベースのマイグレーション時に、テーブルの構造を変更し、古いデータを新しいものに変更しなければならないときによく使われます。
DB::statement('UPDATE users SET role_id = 1 WHERE role_id IS NULL AND YEAR(created_at) > 2020');
さらに、DB::statement()
は、値や列に限定されないスキーマを持つ任意の SQLクエリを実行することができます。以下がその例です。
DB::statement('DROP TABLE users');
DB::statement('ALTER TABLE projects AUTO_INCREMENT=123');
まとめ
ここまでで、Laravelのトランザクション処理とその実装方法について、理解を深めることができたはずです。データの整合性を助けるだけでなく、Laravelのパフォーマンスを最適化しながら、開発プロセスを容易にすることができますので、是非ともご活用ください。
アプリケーション、データベース、WordPressサイトのすべてを一箇所で。Kinstaの高性能クラウドプラットフォームでは、次のような便利な性能や機能の数々をご用意しています。
- MyKinstaでの簡単な設定と管理
- 24時間年中無休のWordPressエンジニアによるサポート
- 最高レベルのGoogle Cloud Platformハードウェアとネットワーク(Kubernetesにより優れた拡張性を実現)
- 速度と堅牢性を両立するエンタープライズレベルのCloudflare統合
- 世界各地35箇所のデータセンターと275に達するPoP(世界規模でオーディエンスに訴求可能)
アプリケーションホスティングまたはデータベースホスティングの初月を20ドル割引でお試しいただけます。プラン一覧をご覧いただくか、営業までお気軽にお問い合わせください。
【4つの方法】WordPressサイトでコメントを一括削除するには