Page Contents
This is a community translation into Chinese. For the latest information, see the English version.
Note:
从loopback-datasource-juggler 2.28.0版本开始支持事务
概要
当模型使用的是如下connector的时候支持实物:
- MySQL connector (主要: 只支持使用InnoDB作为存储引擎)
- PostgreSQL connector
- SQL Server connector
- Oracle 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。
Important:
Oracle只支持READ_COMMITTED 和 SERIALIZABLE.
更多关于隔离级别的信息,见:
- MySQL SET TRANSACTION Syntax
- Oracle Isolation Levels
- PostgreSQL Transaction Isolation
- SQL Server SET TRANSACTION ISOLATION LEVEL
在一个事务里面执行操作
在事务里面执行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();
});
避免长时间的等待和死锁
事务会锁住数据库对象。在一个事务里面异步执行多个方法可能会阻塞别的事务。为了避免长时间的等待和死锁,你应该:
- 尽可能的让事务小
- Don’t serialize execution of methods across multiple transactions