【发布时间】:2019-10-30 21:14:53
【问题描述】:
考虑下面的代码,它从外部服务获取一些数据并将其插入到数据库中的某个表中。它启动事务并在插入所有数据时提交它,如果发生错误则将其回滚:
const mysql = require('mysql2/promise');
class SomeClass
{
async connect(params)
{
this.db = await mysql.createConnection(params);
}
async insertSomeRowsIntoSomeTable()
{
await this.db.execute('START TRANSACTION;');
try {
for (let i = 0; i < 100; i++) {
//get the values to insert from an external service, for example.
await const values = service.getValues();
await this.db.execute('INSERT SomeTable .... <the values>...');
}
await this.db.execute('COMMIT;');
}
catch (e) {
await this.db.execute('ROLLBACK;');
}
}
}
但是,如果有另一个异步方法updateSomething 使用单个更新查询更新某个表中的一行,并且客户端在insertSomeRowsIntoSomeTable 方法仍在运行时调用它怎么办?显然,如果insertSomeRowsIntoSomeTable出现错误,更新后的数据将会丢失。
如果有其他方法发起自己的事务,例如我们意外得到嵌套事务。
我目前唯一的想法是通过将所有事务逻辑移动到存储过程来使数据库的所有操作成为原子操作,但它看起来像是一种解决方法,但不是解决方案。
出于显而易见的原因,不能在每个异步方法中使用单独的数据库连接。
有人有更好的主意吗?
【问题讨论】:
-
不要对实例的所有方法使用单个共享连接(您称之为
db)。在每个事务/方法的连接上使用,并将它们池化。
标签: javascript node.js