nodejs mysql和处理交易 - 代码设计
因此,我对Nodejs并不陌生,这是问题所在。 我们都知道nodejs是单线螺纹,因此我们对任何I/O操作(如文件读取和数据库查询)使用异步操作
考虑以下代码,该代码基本上打开了交易,可以使某些数据库插入和提交:
const mysql = require ("mysql2/promise")
const pool = mysql.createPool({
host: "localhost",
user: "<myuser>",
password: "<mypass>",
database: "<mydb>",
connectionLimit: 10,
});
const test = async function () {
let conn = await pool.getConnection()
await conn.beginTransaction()
await conn.execute("insert into test.temp1 (a) values(?)", [1])
await conn.execute("insert into test.temp1 (a) values(?)", [2])
await conn.commit()
await conn.release()
}
test()
这一切都很好,但这一切都很好,但是真实的实时代码结构更为复杂。一个查询可能会更新用户余额,另一个查询可能会插入日志记录和另一个查询,以在代码(可重用性)中的不同位置插入事务记录),所有这些都在一个事务中。
因此,考虑以下代码,该代码是上述代码的修改版本:
const pool = mysql.createPool({
host: "localhost",
user: "<myuser>",
password: "<mypass>",
database: "<mydb>",
connectionLimit: 10,
});
const function1 = async function (params){
let conn = await pool.getConnection()
await conn.execute("insert into test.temp1 (a) values(?)", [params])
throw new Error("error in my code")
}
const test = async function () {
let conn = await pool.getConnection()
await conn.beginTransaction()
await function1(1)
await function1(2)
await conn.commit()
await conn.release()
}
test().catch(async function (err){
let conn = await pool.getConnection()
conn.rollback()
console.log(err)
})
问题是内部呼叫使用的连接与打开交易的连接不同,因此交易块不起作用,
我无法将连接存储在某些中静态资源并在我的内部函数中使用它,因为它是所有运行代码的单线螺纹和共享的
是我的解决方案,可以通过连接到所有类/函数?这并不是
我应该用来更好地支持交易的其他设计模式吗?
so, I am little new to NodeJS and here is the issue.
We all know NodeJS is single threaded and thus we use async operations for any I/O operation like file reading and database queries
consider the following code which basically opens a transaction, makes some DB insert and commit :
const mysql = require ("mysql2/promise")
const pool = mysql.createPool({
host: "localhost",
user: "<myuser>",
password: "<mypass>",
database: "<mydb>",
connectionLimit: 10,
});
const test = async function () {
let conn = await pool.getConnection()
await conn.beginTransaction()
await conn.execute("insert into test.temp1 (a) values(?)", [1])
await conn.execute("insert into test.temp1 (a) values(?)", [2])
await conn.commit()
await conn.release()
}
test()
this is all fine and dandy, but real live code structure is more complex. One query might update a user balance, another query might insert a log record and another query to insert a transactions record in different locations in code (reusability) )and all of that in one transaction.
so, consider the below code which is a modified version of the above code:
const pool = mysql.createPool({
host: "localhost",
user: "<myuser>",
password: "<mypass>",
database: "<mydb>",
connectionLimit: 10,
});
const function1 = async function (params){
let conn = await pool.getConnection()
await conn.execute("insert into test.temp1 (a) values(?)", [params])
throw new Error("error in my code")
}
const test = async function () {
let conn = await pool.getConnection()
await conn.beginTransaction()
await function1(1)
await function1(2)
await conn.commit()
await conn.release()
}
test().catch(async function (err){
let conn = await pool.getConnection()
conn.rollback()
console.log(err)
})
the issue is that the inner calls are using a different connection then the connection that opened the transaction and thus the transaction block is not working
I cannot store the connection in some static resource and use it in my inner functions because it is single threaded and shared by all running code
is my solution to pass around the connection to all classes/functions? This is not much fun
any other design pattern that I should use to better support transactions?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论