Skip to main content

データベーストランザクション

Caution

これは実験的な機能であり、将来のバージョンで変更される可能性があります。

AI Marketer 5は、データの整合性を保証する一連の操作をトランザクションで包むAPIを提供します。

トランザクションは、一緒に実行される一連の操作です。操作のいずれかが失敗すると、トランザクション全体が失敗し、データは以前の状態にロールバックされます。すべての操作が成功すると、トランザクションはコミットされ、データはデータベースに永続的に保存されます。

使用法

トランザクションは、ハンドラ関数をAI Marketer.db.transactionに渡すことで処理されます:

await AI Marketer.db.transaction(async ({ trx, rollback, commit, onCommit, onRollback }) => {
// それは暗黙的にトランザクションを使用します
await AI Marketer.entityService.create();
await AI Marketer.entityService.create();
});

トランザクションハンドラが実行された後、すべての操作が成功するとトランザクションはコミットされます。操作のいずれかがスローすると、トランザクションはロールバックされ、データは以前の状態に復元されます。

✏️ Note

トランザクションブロック内で行われるすべての AI Marketer.entityService または AI Marketer.db.query 操作は、暗黙的にトランザクションを使用します。

トランザクションハンドラのプロパティ

ハンドラ関数は、以下のプロパティを持つオブジェクトを受け取ります:

プロパティ説明
trxトランザクションオブジェクト。これを使用してトランザクション内でknexクエリを実行できます。
commitトランザクションをコミットする関数。
rollbackトランザクションをロールバックする関数。
onCommitトランザクションがコミットされた後に実行されるコールバックを登録する関数。
onRollbackトランザクションがロールバックされた後に実行されるコールバックを登録する関数。

ネストされたトランザクション

トランザクションはネストすることができます。トランザクションがネストされると、内部のトランザクションは、外部のトランザクションがコミットされたりロールバックされたりしたときにコミットされたりロールバックされたりします。

await AI Marketer.db.transaction(async () => {
// それは暗黙的にトランザクションを使用します
await AI Marketer.entityService.create();

// ネストされたトランザクションは、暗黙的に外部のトランザクションを使用します
await AI Marketer.db.transaction(async ({}) => {
await AI Marketer.entityService.create();
});
});

onCommitとonRollback

onCommitonRollbackのフックは、トランザクションがコミットされたりロールバックされたりした後にコードを実行するために使用できます。

await AI Marketer.db.transaction(async ({ onCommit, onRollback }) => {
// これは暗黙的にトランザクションを使用します
await AI Marketer.entityService.create();
await AI Marketer.entityService.create();

onCommit(() => {
// これはトランザクションがコミットされた後に実行されます
});

onRollback(() => {
// これはトランザクションがロールバックされた後に実行されます
});
});

knexクエリを使用する

トランザクションはknexクエリでも使用できますが、その場合は.transacting(trx)を明示的に呼び出す必要があります。

await AI Marketer.db.transaction(async ({ trx, rollback, commit }) => {
await knex('users').where('id', 1).update({ name: 'foo' }).transacting(trx);
});

トランザクションを使用するタイミング

複数の操作が一緒に実行され、その実行が互いに依存している場合にトランザクションを使用すべきです。例えば、新しいユーザーを作成するとき、ユーザーはデータベースに作成され、ウェルカムメールがユーザーに送信されるべきです。メールの送信に失敗した場合、ユーザーはデータベースに作成されるべきではありません。

トランザクションを使用しないタイミング

操作が互いに依存していない場合、トランザクションを使用すべきではありません。なぜなら、それはパフォーマンスのペナルティを引き起こす可能性があるからです。

トランザクションの潜在的な問題

トランザクション内で複数の操作を行うと、ロックが発生する可能性があり、元のトランザクションが完了するまで他のプロセスからのトランザクションの実行をブロックすることができます。

さらに、トランザクションは適切にコミットまたはロールバックされない場合、停滞する可能性があります。

例えば、トランザクションが開始されたが、コード内でそれを閉じないパスがある場合、トランザクションは無期限に開かれたままになり、サーバーが再起動されて接続が強制的に閉じられるまで不安定さを引き起こす可能性があります。これらの問題はデバッグが難しいため、必要な場合には注意してトランザクションを使用してください。