diff --git a/index.js b/index.js index 05001c5f..76c8b1c3 100644 --- a/index.js +++ b/index.js @@ -12,3 +12,5 @@ var commonTest = './test/common_test'; Object.defineProperty(exports, 'test', { get: function() {return require(commonTest);} }); + +exports.Transaction = require('loopback-connector').Transaction; diff --git a/lib/dao.js b/lib/dao.js index 8492c3bc..102c7c02 100644 --- a/lib/dao.js +++ b/lib/dao.js @@ -2324,3 +2324,8 @@ jutil.mixin(DataAccessObject, Inclusion); * Add 'relation' */ jutil.mixin(DataAccessObject, Relation); + +/* + * Add 'transaction' + */ +jutil.mixin(DataAccessObject, require('./transaction')); diff --git a/lib/transaction.js b/lib/transaction.js new file mode 100644 index 00000000..7d1260de --- /dev/null +++ b/lib/transaction.js @@ -0,0 +1,55 @@ +var Transaction = require('loopback-connector').Transaction; + +module.exports = TransactionMixin; + +function TransactionMixin() { +} + +/** + * Begin a new transaction + * @param {Object|String} [options] Options can be one of the forms: + * - Object: {isolationLevel: '...', timeout: 1000} + * - String: isolationLevel + * + * Valid values of `isolationLevel` are: + * + * - Transaction.READ_COMMITTED = 'READ COMMITTED'; // default + * - Transaction.READ_UNCOMMITTED = 'READ UNCOMMITTED'; + * - Transaction.SERIALIZABLE = 'SERIALIZABLE'; + * - Transaction.REPEATABLE_READ = 'REPEATABLE READ'; + * + * @param {Function} cb Callback function. It calls back with (err, transaction). + * To pass the transaction context to one of the CRUD methods, use the `options` + * argument with `transaction` property, for example, + * + * ```js + * + * MyModel.beginTransaction('READ COMMITTED', function(err, tx) { + * MyModel.create({x: 1, y: 'a'}, {transaction: tx}, function(err, inst) { + * MyModel.find({x: 1}, {transaction: tx}, function(err, results) { + * // ... + * tx.commit(function(err) {...}); + * }); + * }); + * }); + * ``` + * + * The transaction can be committed or rolled back. If timeout happens, the + * transaction will be rolled back. Please note a transaction is typically + * associated with a pooled connection. Committing or rolling back a transaction + * will release the connection back to the pool. + * + */ +TransactionMixin.beginTransaction = function(options, cb) { + if (Transaction) { + var connector = this.getConnector(); + Transaction.begin(connector, options, cb); + } else { + process.nextTick(function() { + var err = new Error('Transaction is not supported'); + cb(err); + }); + } +}; + +