Skip to content

Commit d983478

Browse files
authored
fix: handle concurrent transaction (#85)
1 parent fb81c4e commit d983478

File tree

3 files changed

+31
-2
lines changed

3 files changed

+31
-2
lines changed

lib/client.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,12 +79,16 @@ proto.beginTransaction = function* () {
7979
proto.beginTransactionScope = function* (scope, ctx) {
8080
ctx = ctx || {};
8181
if (!ctx._transactionConnection) {
82-
ctx._transactionConnection = yield this.beginTransaction();
82+
// Create only one conn if concurrent call `beginTransactionScope`
83+
ctx._transactionConnection = this.beginTransaction();
84+
}
85+
const tran = yield ctx._transactionConnection;
86+
87+
if (!ctx._transactionScopeCount) {
8388
ctx._transactionScopeCount = 1;
8489
} else {
8590
ctx._transactionScopeCount++;
8691
}
87-
const tran = ctx._transactionConnection;
8892
try {
8993
const result = yield scope(tran);
9094
ctx._transactionScopeCount--;

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
"eslint-config-egg": "^3.2.0",
2525
"istanbul": "*",
2626
"mocha": "8",
27+
"mz-modules": "^2.1.0",
2728
"thunk-mocha": "*"
2829
},
2930
"homepage": "https://github.com/ali-sdk/ali-rds",

test/client.test.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ const assert = require('assert');
55
const mysql = require('mysql');
66
const rds = require('../');
77
const config = require('./config');
8+
const sleep = require('mz-modules/sleep');
89

910
describe('client.test.js', function() {
1011
const prefix = 'prefix-' + process.version + '-';
@@ -414,6 +415,29 @@ describe('client.test.js', function() {
414415
assert.equal(ctx._transactionScopeCount, 3);
415416
});
416417
});
418+
419+
it('should safe with yield Array', function* () {
420+
const ctx = {};
421+
yield [
422+
this.db.beginTransactionScope(function* (conn) {
423+
yield conn.query(
424+
'INSERT INTO `ali-sdk-test-user` (name, email, mobile) values(?, ?, "12345678901")',
425+
[ prefix + 'should-safe-with-yield-array-1', prefix + 'm@should-safe-with-yield-array-1.com' ]
426+
);
427+
yield sleep(100);
428+
}, ctx),
429+
this.db.beginTransactionScope(function* (conn) {
430+
yield conn.query(
431+
'INSERT INTO `ali-sdk-test-user` (name, email, mobile) values(?, ?, "12345678901")',
432+
[ prefix + 'should-safe-with-yield-array-2', prefix + 'm@should-safe-with-yield-array-1.com' ]
433+
);
434+
yield sleep(200);
435+
}, ctx),
436+
];
437+
const rows = yield this.db.query(
438+
'SELECT * FROM `ali-sdk-test-user` where name like "%should-safe-with-yield-array%"');
439+
assert(rows.length === 2);
440+
});
417441
});
418442

419443
describe('beginDoomedTransactionScope(scope)', function() {

0 commit comments

Comments
 (0)