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

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 ...@@ -13,6 +13,8 @@ Notice how the callback passed to `transaction` returns a promise chain, and doe
```js ```js
return sequelize.transaction(function (t) { return sequelize.transaction(function (t) {
// chain all your queries here. make sure you return them.
return User.create({ return User.create({
firstName: 'Abraham', firstName: 'Abraham',
lastName: 'Lincoln' lastName: 'Lincoln'
...@@ -22,6 +24,7 @@ return sequelize.transaction(function (t) { ...@@ -22,6 +24,7 @@ return sequelize.transaction(function (t) {
lastName: 'Boothe' lastName: 'Boothe'
}, {transaction: t}); }, {transaction: t});
}); });
}).then(function (result) { }).then(function (result) {
// Transaction has been committed // Transaction has been committed
// result is whatever the result of the promise chain returned to the transaction callback // result is whatever the result of the promise chain returned to the transaction callback
...@@ -31,6 +34,8 @@ return sequelize.transaction(function (t) { ...@@ -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: 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 ```js
...@@ -45,6 +50,8 @@ return sequelize.transaction(function (t) { ...@@ -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: 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 ```js
...@@ -67,11 +74,11 @@ CLS works like a thread-local storage for callbacks. What this means in practice ...@@ -67,11 +74,11 @@ CLS works like a thread-local storage for callbacks. What this means in practice
```js ```js
sequelize.transaction(function (t1) { sequelize.transaction(function (t1) {
namespace.get('transaction') === t1; namespace.get('transaction') === t1; // true
}); });
sequelize.transaction(function (t2) { sequelize.transaction(function (t2) {
namespace.get('transaction') === t2; namespace.get('transaction') === t2; // true
}); });
``` ```
...@@ -84,20 +91,47 @@ sequelize.transaction(function (t1) { ...@@ -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 ```js
sequelize.transaction(function (t1) { sequelize.transaction(function (t1) {
sequelize.transaction(function (t2) { return sequelize.transaction(function (t2) {
// By default queries here will use 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([ return Promise.all([
User.create({ name: 'Bob' }, { transaction: null }), 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 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. 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) { ...@@ -36,10 +36,11 @@ var Transaction = module.exports = function(sequelize, options) {
}; };
/** /**
* The possible isolations levels to use when starting a transaction. * Isolations levels can be set per-transaction by passing `options.isolationLevel` to `sequelize.transaction`.
* 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`. * 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 * ```js
* { * {
* READ_UNCOMMITTED: "READ UNCOMMITTED", * READ_UNCOMMITTED: "READ UNCOMMITTED",
...@@ -49,6 +50,22 @@ var Transaction = module.exports = function(sequelize, options) { ...@@ -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 * @property ISOLATION_LEVELS
*/ */
Transaction.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!