5

Back in the day, it was common to manage database transactions in Java by writing code that did it. Something like this:

Transaction tx = session.startTransaction();
...
try {
 tx.commit();
} catch (SomeException e){
 tx.rollback();
}

at the beginning and end of every method. This had some obvious problems - it's redundant, hides the intent of what's happening, etc. So, along came annotation-driven transactions:

@Transaction
public SomeResultObj getResult(...){
 ...
}

Is there any support for declarative transaction management in node.js?

asked Jun 6, 2014 at 18:50
3
  • didn't know that was ever common... I've always written code to have a central place to execute JDBC code from and handle transactions, it's just a good idea... Commented Jun 11, 2014 at 9:29
  • Most people have avoided writing their own database transaction API because they dislike re-inventing the wheel, combined with the fact that most of the available options are safer, and easier to use than rolling your own. Commented Oct 20, 2014 at 17:59
  • Agreed with not rolling one's own database transaction API! I would certainly like to know if there are any existing declarative database transaction APIs in Node.js. Commented Oct 20, 2014 at 18:40

1 Answer 1

2

In case you're using Express + Sequelize, you can do this by using a module called continuation-local-storage (henceforth cls, for brevity).

Show me the code

// When initializing your Sequelize instance
var Sequelize = require( "sequelize" );
Sequelize.cls = require( "continuation-local-storage" ).createNamespace( "db" );
module.exports = new Sequelize(...);

Then, create some middleware to initialize your transaction in every request (in case no one has come up with one yet):

var sequelize = require(...);
app.use(function ( req, res, next ) {
 sequelize.transaction(function () {
 // Do something else, but be sure to invoke next middleware
 next(); 
 });
});

What's going on here?

  1. A cls namespace is declared for Sequelize to use. Must be set on the constructor;
  2. A transaction is initialized in an Express middleware;
  3. Every subsequent sequelize query will use the request transaction by default (you can override this behavior, obviously).

How this works?

This works because cls assigns a new storage for each new async chain (the request in this example), and they are passed down consistently and transparently.
It's some kind of magic that happens inside Node :)

Tips

It's very likely that you'll need to use some monkeypatch to take that approach. Depends on your Promises implementation.

Further info

Check the Sequelize documentation.

answered Aug 20, 2015 at 12:04

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.