diff --git a/lib/datasource.js b/lib/datasource.js index 2603e5b8..4e92d96c 100644 --- a/lib/datasource.js +++ b/lib/datasource.js @@ -2648,6 +2648,17 @@ DataSource.prototype.execute = function(command, args = [], options = {}) { } }; +/** + * Begin a new Transaction. + * + * + * @param [options] Options {isolationLevel: '...', timeout: 1000} + * @returns Promise A promise which resolves to a Transaction object + */ +DataSource.prototype.beginTransaction = function(options) { + return Transaction.begin(this.connector, options); +}; + /*! The hidden property call is too expensive so it is not used that much */ /** diff --git a/test/transaction.test.js b/test/transaction.test.js index c84946ef..8f2ae740 100644 --- a/test/transaction.test.js +++ b/test/transaction.test.js @@ -71,6 +71,13 @@ describe('Transactions on test connector without execute()', () => { }, done); }); + it('beginTransaction returns a transaction', async () => { + const promise = db.beginTransaction(Transaction.READ_UNCOMMITTED); + promise.should.be.Promise(); + const transaction = await promise; + transaction.should.be.instanceof(EventEmitter); + }); + it('exposes and caches slave models', done => { testModelCaching(tx.models, db.models); done(); diff --git a/types/datasource.d.ts b/types/datasource.d.ts index 2609405b..b7fadf82 100644 --- a/types/datasource.d.ts +++ b/types/datasource.d.ts @@ -12,6 +12,7 @@ import { PropertyDefinition, } from './model'; import {EventEmitter} from 'events'; +import {IsolationLevel, Transaction} from './transaction-mixin'; /** * LoopBack models can manipulate data via the DataSource object. @@ -185,4 +186,15 @@ export declare class DataSource extends EventEmitter { args?: any[] | object, options?: Options ): Promise; + +/** + * Begin a new transaction. + * + * + * @param [options] Options {isolationLevel: '...', timeout: 1000} + * @returns Promise A promise which resolves to a Transaction object + */ + beginTransaction( + options?: IsolationLevel | Options, + ): PromiseOrVoid; } diff --git a/types/persisted-model.d.ts b/types/persisted-model.d.ts index df9c2d54..c908e741 100644 --- a/types/persisted-model.d.ts +++ b/types/persisted-model.d.ts @@ -6,7 +6,6 @@ import {Callback, Options, PromiseOrVoid} from './common'; import {ModelBase, ModelData} from './model'; import {Filter, Where} from './query'; -import {Transaction} from './transaction-mixin'; /** * Data object for persisted models @@ -478,58 +477,6 @@ export declare class PersistedModel extends ModelBase { callback?: Callback, ): PromiseOrVoid; -/** - * Begin a new transaction. - * - * A 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. - * - * Once the transaction is committed or rolled back, the connection property - * will be set to null to mark the transaction to be inactive. Trying to commit - * or rollback an inactive transaction will receive an error from the callback. - * - * Please also note that the transaction is only honored with the same data - * source/connector instance. CRUD methods will not join the current transaction - * if its model is not attached the same data source. - * - * Example: - * - * 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) {...}); - * }); - * }); - * }); - * ``` - * - * @param {Object|String} options Options to be passed upon transaction. - * - * 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'; - * @callback {Function} cb Callback function. - * @returns {Promise|undefined} Returns a callback promise. - */ - beginTransaction( - options?: string | Options, - callback?: Callback, - ): PromiseOrVoid; - /** * Reload object from persistence. Requires `id` member of `object` to be able to call `find`. * @callback {Function} callback Callback function called with `(err, instance)` arguments. Required.