From d983478d40203357c71187c94f44ef3afab0b604 Mon Sep 17 00:00:00 2001 From: killa Date: Thu, 11 Feb 2021 22:03:28 +0800 Subject: [PATCH] fix: handle concurrent transaction (#85) --- lib/client.js | 8 ++++++-- package.json | 1 + test/client.test.js | 24 ++++++++++++++++++++++++ 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/lib/client.js b/lib/client.js index b486753..4d3098d 100644 --- a/lib/client.js +++ b/lib/client.js @@ -79,12 +79,16 @@ proto.beginTransaction = function* () { proto.beginTransactionScope = function* (scope, ctx) { ctx = ctx || {}; if (!ctx._transactionConnection) { - ctx._transactionConnection = yield this.beginTransaction(); + // Create only one conn if concurrent call `beginTransactionScope` + ctx._transactionConnection = this.beginTransaction(); + } + const tran = yield ctx._transactionConnection; + + if (!ctx._transactionScopeCount) { ctx._transactionScopeCount = 1; } else { ctx._transactionScopeCount++; } - const tran = ctx._transactionConnection; try { const result = yield scope(tran); ctx._transactionScopeCount--; diff --git a/package.json b/package.json index da2f487..ef26e93 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "eslint-config-egg": "^3.2.0", "istanbul": "*", "mocha": "8", + "mz-modules": "^2.1.0", "thunk-mocha": "*" }, "homepage": "https://github.com/ali-sdk/ali-rds", diff --git a/test/client.test.js b/test/client.test.js index c1246dd..a090be6 100644 --- a/test/client.test.js +++ b/test/client.test.js @@ -5,6 +5,7 @@ const assert = require('assert'); const mysql = require('mysql'); const rds = require('../'); const config = require('./config'); +const sleep = require('mz-modules/sleep'); describe('client.test.js', function() { const prefix = 'prefix-' + process.version + '-'; @@ -414,6 +415,29 @@ describe('client.test.js', function() { assert.equal(ctx._transactionScopeCount, 3); }); }); + + it('should safe with yield Array', function* () { + const ctx = {}; + yield [ + this.db.beginTransactionScope(function* (conn) { + yield conn.query( + 'INSERT INTO `ali-sdk-test-user` (name, email, mobile) values(?, ?, "12345678901")', + [ prefix + 'should-safe-with-yield-array-1', prefix + 'm@should-safe-with-yield-array-1.com' ] + ); + yield sleep(100); + }, ctx), + this.db.beginTransactionScope(function* (conn) { + yield conn.query( + 'INSERT INTO `ali-sdk-test-user` (name, email, mobile) values(?, ?, "12345678901")', + [ prefix + 'should-safe-with-yield-array-2', prefix + 'm@should-safe-with-yield-array-1.com' ] + ); + yield sleep(200); + }, ctx), + ]; + const rows = yield this.db.query( + 'SELECT * FROM `ali-sdk-test-user` where name like "%should-safe-with-yield-array%"'); + assert(rows.length === 2); + }); }); describe('beginDoomedTransactionScope(scope)', function() {