LoginSignup
2
1

More than 5 years have passed since last update.

Node.js向けORM Objection.jsを使ってみた(4) - トランザクション

Last updated at Posted at 2018-08-19

概要

トランザクションの利用方法は2種類あります。

  • クエリを実行する際に、明示的にTransactionオブジェクトを受け渡す
  • ModelをTransactionオブジェクトに束縛する

明示的にTransactionオブジェクトを受け渡す

const { transaction } = require('objection');

await transaction(Project.knex(), async trx => {
  const project = await Project
    .query(trx)
    .insert({ name: 'hoge' });

  await project
    .$relatedQuery('members', trx) 
    .insert({ name: 'hogepiyo', email: 'hogepiyo@example.com' });
});

transaction関数を実行することで、トランザクションを開始します。

第1引数にはknexインスタンス、第2引数にはコールバック関数を渡します。

knexインスタンスは、任意のModelのknexメソッド等で取得できます。

第2引数のコールバック関数は、引数としてTransactionオブジェクトを受け取ります。

このTransactionオブジェクトを、query, $query, または$relatedQueryメソッドの最後の引数として渡すことで、クエリがトランザクション内で実行されます。

コールバック関数が返却したPromiseがresolveされると、トランザクションはコミットされます。

コールバック関数で返却されたPromiseがrejectされた場合、またはコールバック内で例外が発生した場合は、トランザクションはロールバックされます。

ModelをTransactionオブジェクトに束縛する

const { transaction } = require('objection');

await transaction(Project, Task, async (Project, Task) => {
  // 引数のProject, Taskを介して発行されるクエリは、自動的にトランザクション内で実行される
  const project = await Project
    .query()
    .insert({ name: 'hoge' });

  const task = await Task
    .query()
    .insert({ name: 'sample', projectId: project.id });

  // Transactionが束縛されたModelのインスタンスを使用してクエリを発行する際も、
  // 同一トランザクション内で実行される
  const users = await project
    .$relatedQuery('members') 
    .insert({ name: 'hogepiyo', email: 'hogepiyo@example.com' });

  // 引数のProject, Task以外のModelからクエリを発行すると、そのクエリはトランザクション内で処理されないので注意 
  // User
  //   .query()
  //   .insert({ name: 'fuga', email: 'fuga@example.com' });
});

transaction関数に、トランザクションを束縛したいModelを渡します。

最後の引数のコールバック関数には、Modelのコピーが渡されます。

Modelのコピーを介してクエリーを発行すると、各クエリが同一トランザクション内で実行されます。

Modelのコピー以外からクエリーを発行すると、同一トランザクション内では実行されないので注意が必要です。

参考元

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1