【发布时间】:2014-11-22 21:56:29
【问题描述】:
我在使用 node.js 和 mysql 的事务方面遇到问题。问题是我的事务不是独立运行的,即使我将隔离级别设置为“可序列化”。
我设置了以下最小示例来举例说明我的问题。我正在使用带有两个列(id,val)的单个表:
CREATE TABLE `A` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`val` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `A` (`id`, `val`) VALUES (1,0);
请注意,我取消了 InnoDB 表类型,因为它支持事务。
我的 node.js 程序只是从表 A 中的单行读取值,并使用更新语句递增它。 select 语句使用 FOR UPDATE 修饰符来获得对行的锁定。两条sql语句被包装成一个事务,我在一个for循环中执行了其中的10个事务:
var orm = require("orm");
orm.connect("mysql://root@localhost/test", function (err, db) {
db.driver.execQuery("SET GLOBAL tx_isolation='SERIALIZABLE';", function (err, data) {
for (var i = 0; i < 10; i++) {
db.driver.execQuery("START TRANSACTION;", function (err, data) {
db.driver.execQuery("SELECT * FROM A FOR UPDATE;", function (err, data) {
var value = data[0].val
console.log('reading value: ',value)
db.driver.execQuery("UPDATE A SET val="+value+"+1 WHERE id=1", function (err, data) {
console.log('writing value: ', value+1)
db.driver.execQuery("COMMIT;", function (err, data) {})
})
})
})
}
})
})
我希望在运行这段代码之后,存储在表 A 中的值会增加 10。然而,它只是增加了 1。
为了了解发生了什么,我在代码中添加了打印输出。我希望看到打印输出
reading value 0
writing value 1
reading value 1
writing value 2
...
但是我得到了打印输出
reading value 0
reading value 0
...
writing value 1
writing value 1
...
解决问题的一种方法是为每个事务建立一个新的数据库连接,但出于性能原因,我不希望这样做。
有人可以解释发生了什么,以及如何将上述内容更改为 node.js 中事务的工作示例吗?
【问题讨论】:
标签: mysql node.js transactions serializable isolation