不要怂,就是干,撸起袖子干!

Commit 83a9103e by Ruben Bridgewater

Help updating the docs. Closes #3710

1 parent 91b33835
Showing with 59 additions and 8 deletions
......@@ -13,6 +13,8 @@ Notice how the callback passed to `transaction` returns a promise chain, and doe
```js
return sequelize.transaction(function (t) {
// chain all your queries here. make sure you return them.
return User.create({
firstName: 'Abraham',
lastName: 'Lincoln'
......@@ -22,6 +24,7 @@ return sequelize.transaction(function (t) {
lastName: 'Boothe'
}, {transaction: t});
});
}).then(function (result) {
// Transaction has been committed
// result is whatever the result of the promise chain returned to the transaction callback
......@@ -31,6 +34,8 @@ return sequelize.transaction(function (t) {
});
```
### Throw errors to rollback
When using the managed transaction you should _never_ commit or rollback the transaction manually. If all queries are successful, but you still want to rollback the transaction (for example because of a validation failure) you should throw an error to break and reject the chain:
```js
......@@ -45,6 +50,8 @@ return sequelize.transaction(function (t) {
});
```
### Automatically pass transactions to all queries
In the examples above, the transaction is still manually passed, by passing `{ transaction: t }` as the second argument. To automatically pass the transaction to all queries you must install the [continuation local storage](https://github.com/othiym23/node-continuation-local-storage) (CLS) module and instantiate a namespace in your own code:
```js
......@@ -67,11 +74,11 @@ CLS works like a thread-local storage for callbacks. What this means in practice
```js
sequelize.transaction(function (t1) {
namespace.get('transaction') === t1;
namespace.get('transaction') === t1; // true
});
sequelize.transaction(function (t2) {
namespace.get('transaction') === t2;
namespace.get('transaction') === t2; // true
});
```
......@@ -84,20 +91,47 @@ sequelize.transaction(function (t1) {
});
```
If you want to execute queries inside the callback without using the transaction you can pass `{ transaction: null }`, or another transaction if you have several concurrent ones:
# Concurrent/Partial transactions
You can have concurrent transactions within a sequence of queries or have some of them excluded from any transactions. Use the `{transaction: }` option to control which transaction a query belong to:
### Without CLS enabled
```js
sequelize.transaction(function (t1) {
sequelize.transaction(function (t2) {
// By default queries here will use t2
return sequelize.transaction(function (t2) {
// With CLS enable, queries here will by default use t2
// Pass in the `transaction` option to define/alter the transaction they belong to.
return Promise.all([
User.create({ name: 'Bob' }, { transaction: null }),
User.create({ name: 'Mallory' }, { transaction: t1 })
User.create({ name: 'Mallory' }, { transaction: t1 }),
User.create({ name: 'John' }) // this would default to t2
]);
});
});
```
# Isolation levels
The possible isolations levels to use when starting a transaction:
```js
Sequelize.Transaction.READ_UNCOMMITTED // "READ UNCOMMITTED"
Sequelize.Transaction.READ_COMMITTED // "READ COMMITTED"
Sequelize.Transaction.REPEATABLE_READ // "REPEATABLE READ"
Sequelize.Transaction.SERIALIZABLE // "SERIALIZABLE"
```
By default, sequelize uses "REPEATABLE READ". If you want to use a different isolation level, pass in the desired level as the first argument:
```js
return sequelize.transaction({
isolationLevel: Sequelize.Transaction.SERIALIZABLE
}, function (t) {
// your transactions
});
```
# Unmanaged transaction (then-callback)
Unmanaged transactions force you to manually rollback or commit the transaction. If you don't do that, the transaction will hang until it times out. To start an unmanaged transaction, call `sequelize.transaction()` without a callback (you can still pass an options object) and call `then` on the returned promise.
......
......@@ -36,10 +36,11 @@ var Transaction = module.exports = function(sequelize, options) {
};
/**
* The possible isolations levels to use when starting a transaction.
* Can be set per-transaction by passing `options.isolationLevel` to `sequelize.transaction`.
* Isolations levels can be set per-transaction by passing `options.isolationLevel` to `sequelize.transaction`.
* Default to `REPEATABLE_READ` but you can override the default isolation level by passing `options.isolationLevel` in `new Sequelize`.
*
* The possible isolations levels to use when starting a transaction:
*
* ```js
* {
* READ_UNCOMMITTED: "READ UNCOMMITTED",
......@@ -49,6 +50,22 @@ var Transaction = module.exports = function(sequelize, options) {
* }
* ```
*
* Pass in the desired level as the first argument:
*
* ```js
* return sequelize.transaction({
* isolationLevel: Sequelize.Transaction.SERIALIZABLE
* }, function (t) {
*
* // your transactions
*
* }).then(function(result) {
* // transaction has been committed. Do something after the commit if required.
* }).catch(function(err) {
* // do something with the err.
* });
* ```
*
* @property ISOLATION_LEVELS
*/
Transaction.ISOLATION_LEVELS = {
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!