-
Notifications
You must be signed in to change notification settings - Fork 96
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added hooks to support mongo-db transaction
- Loading branch information
1 parent
e23ecf1
commit 68e0525
Showing
3 changed files
with
160 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,8 @@ | ||
const hooks = require('./hooks'); | ||
const service = require('./service'); | ||
const transactionManager = require('./transaction-manager'); | ||
|
||
Object.assign(service, { hooks, service }); | ||
|
||
module.exports = service; | ||
module.exports.TransactionManager = transactionManager; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
const errors = require('@feathersjs/errors'); | ||
const mongoose = require('mongoose'); | ||
|
||
/** | ||
* To start a new session and initiate transaction on the session and set | ||
* mongoose-session in context-params to all consecutive service call if the | ||
* boolean | ||
* | ||
* @param {object} context context and all params | ||
* @param {[string]} skipPath list of paths to exclude from transaction | ||
* - Example: ['login'] | ||
* @return {object} context context with db-session appended | ||
*/ | ||
const beginTransaction = async (context, skipPath) => { | ||
try { | ||
// if the current path is not added to skipPath-list | ||
if (skipPath.indexOf(context.path) === -1) { | ||
// if there is no open-transaction appended already | ||
if (context.params && !context.params.transactionOpen) { | ||
const session = await mongoose.startSession(); | ||
session.startTransaction(); | ||
context.params.transactionOpen = true; | ||
context.params.mongoose = { session }; | ||
} | ||
context.enableTransaction = true; // true if transaction is enabled | ||
} else { | ||
context.enableTransaction = false; | ||
} | ||
return context; | ||
} catch (err) { | ||
throw new errors.MongoError(`Error while starting session`); | ||
} | ||
}; | ||
|
||
/** | ||
* To commit a mongo-transaction after save methods of mongo service | ||
* | ||
* @param {object} context context with params, result and DB-session | ||
* @return {object} context context with params, result and DB-session | ||
*/ | ||
const commitTransaction = async context => { | ||
try { | ||
// if transaction is enabled during startSession | ||
if (context.enableTransaction) | ||
// if context contains the mongoose session to be committed | ||
if ( | ||
context.params && | ||
context.params.mongoose && | ||
context.params.mongoose.session | ||
) { | ||
await context.params.mongoose.session.commitTransaction(); | ||
context.params.mongoose = null; | ||
context.params.transactionOpen = false; // reset transaction-open | ||
context.enableTransaction = false; | ||
} | ||
return context; | ||
} catch (err) { | ||
throw new errors.MongoError(`Error while commiting transaction`); | ||
} | ||
}; | ||
|
||
/** | ||
* To rollback a mongo-transaction for any error thrown in service calls | ||
* | ||
* @param {object} context context with params and DB-session | ||
* @return {object} context context with params and DB-session | ||
*/ | ||
const rollbackTransaction = async context => { | ||
try { | ||
// if transaction is enabled during startSession | ||
if (context.enableTransaction) | ||
// if context contains the mongoose session to be committed | ||
if ( | ||
context.params && | ||
context.params.mongoose && | ||
context.params.mongoose.session | ||
) { | ||
await context.params.mongoose.session.abortTransaction(); | ||
context.params.mongoose = null; | ||
context.transactionOpen = false; // reset transaction-open | ||
context.enableTransaction = false; | ||
} | ||
return context; | ||
} catch (err) { | ||
throw new errors.MongoError(`Error while rolling-back transaction`); | ||
} | ||
}; | ||
|
||
module.exports = { | ||
beginTransaction, | ||
commitTransaction, | ||
rollbackTransaction | ||
}; |