我在我的应用程序中使用node-mysql。我尝试实施SELECT FOR UPDATE,但我无法让它正常工作。我遇到的问题看起来像下面的代码。下面for循环中的第一个事务没有成功阻止第二个事务。相反,两个事务同时SELECT FOR UPDATE并获得相同的记录。我怎样才能解决这个问题?谢谢!
var testTransaction = function (count) {
connection.beginTransaction(function(err) {
if (err) throw err;
db.query('SELECT * FROM myTable WHERE id = 1 FOR UPDATE', function(err, rows, result) {
if (err) {
connection.rollback(function() {
throw err;
});
}
connection.query('UPDATE myTable SET myField=? WHERE id=1', (count + 1), function(err, result) {
if (err) {
db.rollback(function() {
throw err;
});
}
connection.commit(function(err) {
if (err) {
db.rollback(function() {
throw err;
});
}
console.log('success!');
});
});
});
});
}
for (var i = 0; i < 2; i++) {
testTransaction(i);
}
答案 0 :(得分:0)
node-mysql模块中的方法被编写为异步,因此不会阻止应用程序。如果您没有理由使用循环,那么您只需向函数添加一个回调并嵌套执行:
var testTransaction = function(count, callback) {
connection.beginTransaction(function (err) {
if (err) throw err;
db.query('SELECT * FROM myTable WHERE id = 1 FOR UPDATE', function (err, rows, result) {
if (err) {
connection.rollback(function() {
return callback(err);
});
}
connection.query('UPDATE myTable SET myField=? WHERE id=1', (count + 1), function (err, result) {
if (err) {
db.rollback(function() {
return callback(err);
});
}
connection.commit(function (err) {
if (err) {
db.rollback(function() {
return callback(err);
});
}
callback(null);
console.log('success!');
});
});
});
});
};
testTransaction(0, function(err) {
testTransaction(1, function(err) {
// both operations have completed
});
});
如果由于某种原因需要循环异步函数,那么我将查看async库。
答案 1 :(得分:0)
您的问题是您使用相同的连接。
尝试这样的事情:
var mysql = require('mysql');
function conn() {
var connection = mysql.createConnection({
host : 'localhost',
user : 'user',
password : 'pass',
database : 'test'
});
return connection;
}
var testTransaction = function (connection,count) {
connection.beginTransaction(function(err) {
if (err) throw err;
connection.query('SELECT * FROM table WHERE id = 1 FOR UPDATE', function(err, rows, result) {
console.log(rows);
if (err) {
connection.rollback(function() {
throw err;
});
}
connection.query('UPDATE table SET name=? WHERE id=1', (count + 1), function(err, result) {
if (err) {
connection.rollback(function() {
throw err;
});
}
setTimeout(function(){
connection.commit(function(err) {
if (err) {
connection.rollback(function() {
throw err;
});
}
console.log('success!');
});
},2000);
});
});
});
}
for (var i = 0; i < 2; i++) {
testTransaction(conn(),i);
}
请注意,它为每个事务使用不同的连接。
在命令行mysql中,您可以通过打开两个连接来复制类似的东西,在两者中发出start transaction
,然后在一个中尝试select ... for update
两次(两次都有效)并且一次另一个(等待第一个)。