Page Contents

概要

当模型使用的是如下connector的时候支持实物:

事务APIs

点击API reference查看完整的事务API文档。

在一个事务里面执行操作有下面几个步骤:

  • 开始一个新事务
  • 在事务里面执行CRUD操作
  • 提交(commit)或(rollback)事务

Start transaction

使用beginTransaction方法开始一个新的事务。例子:

Post.beginTransaction({
  isolationLevel: Post.Transaction.READ_COMMITTED
}, function(err, tx) {
  // 现在有了一个事务(tx)
});

隔离级别

当调用beginTransaction(), 你可以在option里面指定一个隔离界别。LoopBack事务支持以下几种隔离级别:

  • Transaction.READ_UNCOMMITTED
  • Transaction.READ_COMMITTED (默认)
  • Transaction.REPEATABLE_READ
  • Transaction.SERIALIZABLE

默认使用READ_COMMITTED。

更多关于隔离级别的信息,见:

在一个事务里面执行操作

在事务里面执行CRUD操作,只需要在标准的create()upsert()destroyAll()等方法的第二个参数加上transaction对象就可以了。

例子:

Post.create({title: 't1', content: 'c1'}, {transaction: tx}, function(err, post) {
  post.updateAttributes({content: 'c2', {transaction: tx}, function(err, newPost) {
    //
    newPost.reviews.create({content: 'r1'}, {transaction: tx}, function(err, newPost) {
    });
  }
});

提交(commit)或回滚(rollback)

提交一个事务:

transaction.commit(function(err) {});

回滚一个事务:

transaction.rollback(function(err) {});

这些API都支持Promise。详见https://github.com/strongloop/loopback-connector-mysql/blob/master/test/transaction.promise.test.js.

设置超时

可以在开始一个事务的时候指定超时事件(单位为毫秒)。如果事务在指定的时间没有结束(提交或回滚),会自动回滚。 超时事件会被timeout钩子捕获。例子:

Post.beginTransaction({
  isolationLevel: Transaction.READ_COMMITTED,
  timeout: 30000 // 30000ms = 30s
}, function(err, tx) {
  tx.observe('timeout', function(context, next) {
    // handle timeout
    next();
  });
});

传播事务

给所有的CRUD方法和关系方法通过option添加一个transaction对象来实现传播事务。例子:

var options = {transaction: tx};
Post.create({title: 't1', content: 'c1'}, options, function(err, post) {
  post.updateAttributes({content: 'c2', options, function(err, newPost) {
    //
    newPost.reviews.create({content: 'r1'}, options, function(err, newPost) {
    });
  }
});

设置事务钩子

事务有下面几种可以被观察监测到的事件:

  • before commit
  • after commit
  • before rollback
  • after rollback
  • timeout
tx.observe('before commit', function(context, next) {
  // ...
  next();
});
tx.observe('after commit', function(context, next) {
  // ...
  next();
});
tx.observe('before rollback', function(context, next) {
  // ...
  next();
});
tx.observe('after rollback', function(context, next) {
  // ...
  next();
});

避免长时间的等待和死锁

事务会锁住数据库对象。在一个事务里面异步执行多个方法可能会阻塞别的事务。为了避免长时间的等待和死锁,你应该:

  1. 尽可能的让事务小
  2. Don’t serialize execution of methods across multiple transactions