Skip to content

Commit

Permalink
datastore: automatically rollback a transaction
Browse files Browse the repository at this point in the history
  • Loading branch information
stephenplusplus committed Jun 13, 2016
1 parent ac0d340 commit 41eec47
Showing 1 changed file with 31 additions and 12 deletions.
43 changes: 31 additions & 12 deletions lib/datastore/transaction.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,12 @@ nodeutil.inherits(Transaction, DatastoreRequest);
/**
* Commit the remote transaction and finalize the current transaction instance.
*
* If the commit request fails, we will automatically rollback the transaction.
*
* @param {function} callback - The callback function.
* @param {?error} callback.err - An error returned while making this request.
* If the commit fails, we automatically try to rollback the transaction (see
* {module:datastore/transaction#rollback}).
* @param {object} callback.apiResponse - The full API response.
*
* @example
Expand All @@ -114,7 +118,7 @@ nodeutil.inherits(Transaction, DatastoreRequest);
* });
*/
Transaction.prototype.commit = function(callback) {
var that = this;
var self = this;

callback = callback || util.noop;

Expand Down Expand Up @@ -179,7 +183,7 @@ Transaction.prototype.commit = function(callback) {
var method = modifiedEntity.method;
var args = modifiedEntity.args.reverse();

DatastoreRequest.prototype[method].call(that, args, util.noop);
DatastoreRequest.prototype[method].call(self, args, util.noop);
});

var protoOpts = {
Expand All @@ -195,14 +199,29 @@ Transaction.prototype.commit = function(callback) {

this.request_(protoOpts, reqOpts, function(err, resp) {
if (err) {
callback(err, resp);
// Rollback automatically for the user.
self.rollback(function(err) {
if (err) {
err.message = [
'The commit was not successful and the transaction could not be',
'rolled back. You may want to try calling transaction.rollback().',
'\n',
'\n',
err.message
].join('');
}

// Provide the response items from the failed commit to the user. A
// successful rollback should be transparent.
callback(err, resp);
});
return;
}

// The `callbacks` array was built previously. These are the callbacks that
// handle the API response normally when using the DatastoreRequest.save and
// .delete methods.
that.requestCallbacks_.forEach(function(cb) {
self.requestCallbacks_.forEach(function(cb) {
cb(null, resp);
});

Expand Down Expand Up @@ -277,10 +296,10 @@ Transaction.prototype.createQuery = function() {
* });
*/
Transaction.prototype.delete = function(entities) {
var that = this;
var self = this;

arrify(entities).forEach(function(ent) {
that.modifiedEntities_.push({
self.modifiedEntities_.push({
entity: {
key: ent
},
Expand Down Expand Up @@ -311,7 +330,7 @@ Transaction.prototype.delete = function(entities) {
* });
*/
Transaction.prototype.rollback = function(callback) {
var that = this;
var self = this;

callback = callback || util.noop;

Expand All @@ -321,7 +340,7 @@ Transaction.prototype.rollback = function(callback) {
};

this.request_(protoOpts, {}, function(err, resp) {
that.skipCommit = true;
self.skipCommit = true;

callback(err || null, resp);
});
Expand Down Expand Up @@ -358,7 +377,7 @@ Transaction.prototype.rollback = function(callback) {
* });
*/
Transaction.prototype.run = function(callback) {
var that = this;
var self = this;

callback = callback || util.noop;

Expand All @@ -373,7 +392,7 @@ Transaction.prototype.run = function(callback) {
return;
}

that.id = resp.transaction;
self.id = resp.transaction;

callback(null, resp);
});
Expand Down Expand Up @@ -491,10 +510,10 @@ Transaction.prototype.run = function(callback) {
* });
*/
Transaction.prototype.save = function(entities) {
var that = this;
var self = this;

arrify(entities).forEach(function(ent) {
that.modifiedEntities_.push({
self.modifiedEntities_.push({
entity: {
key: ent.key
},
Expand Down

0 comments on commit 41eec47

Please sign in to comment.