请问Nodejs的mysql模块为什么无法回滚?
请问Nodejs的mysql模块为什么无法回滚?
按照github中mysql模块的wiki来的,不可用啊。mysql已经设置innodb autocommit也关闭了,代码贴下来,麻烦大家帮忙看看。 connection.beginTransaction(function (err) { if (err) { throw err; res.json({ success : false, err : err }); return ; }
var delete_sql = "delete from tp_lbs where type= ?";
// var delete_sql = 'insert into tp_lbs (name, address, phone, longitude, latitude, type) values (1,2,3,4,5,6)';
connection.query(delete_sql, [type], function (err, result) {
if(err) {
connection.rollback(function() {
throw err;
});
res.json({
success : false,
err : err
});
return ;
}
var sql = "sekect name from tp_lbs where ,.";
connection.query(sql, [], function (err, result) {
if(err) {
connection.rollback(function() {
throw err;
});
res.json({
success : false,
err : err
});
return ;
}
connection.commit(function(err) {
if (err) {
connection.rollback(function() {
throw err;
res.json({
success : false,
err : err
});
return ;
});
}
res.json({
success : false,
err : err
});
});
});
});
});
2 回复
问题描述
在使用 Node.js 的 mysql
模块进行数据库操作时,你遇到了一个问题:在执行事务过程中,即使遇到错误也无法成功回滚。具体来说,你在尝试删除记录后,想要通过回滚来撤销已执行的操作,但发现事务并没有按预期回滚。
原因分析
主要问题出在以下几点:
- SQL 错误处理:在查询 SQL 语句时,你使用了错误的表名或列名(如
sekect
而不是select
),这会导致查询失败,但在捕获到错误后没有正确处理回滚逻辑。 - 事务提交与回滚逻辑:你的代码中,在提交事务时,如果发生错误会触发回滚,但你没有正确处理回滚后的逻辑,导致回滚操作可能被忽略。
示例代码及修正
以下是修正后的代码示例:
const mysql = require('mysql');
// 创建连接
const connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'password',
database: 'testdb'
});
connection.connect((err) => {
if (err) {
console.error('Error connecting to database:', err.stack);
return;
}
console.log('Connected as id ' + connection.threadId);
});
// 开始事务
connection.beginTransaction(function (err) {
if (err) {
throw err;
}
const type = 1; // 假设 type 是你要删除的类型
const delete_sql = "DELETE FROM tp_lbs WHERE type = ?";
connection.query(delete_sql, [type], function (err, result) {
if (err) {
console.error("Delete query failed:", err);
connection.rollback(function () {
console.error("Rollback executed");
});
res.json({
success: false,
err: err
});
return;
}
const select_sql = "SELECT name FROM tp_lbs WHERE type = ?";
connection.query(select_sql, [type], function (err, result) {
if (err) {
console.error("Select query failed:", err);
connection.rollback(function () {
console.error("Rollback executed");
});
res.json({
success: false,
err: err
});
return;
}
connection.commit(function (err) {
if (err) {
console.error("Commit failed, rolling back:", err);
connection.rollback(function () {
console.error("Rollback executed");
});
res.json({
success: false,
err: err
});
return;
}
console.log("Transaction committed successfully");
res.json({
success: true,
data: result
});
});
});
});
});
关键点解释
- 事务开始:使用
beginTransaction()
方法开启事务。 - 错误处理:在每个查询后检查是否有错误,如果有则调用
rollback()
方法进行回滚,并返回错误信息。 - 事务提交:在所有查询都成功后,使用
commit()
方法提交事务。如果提交过程中出现错误,则再次调用rollback()
方法进行回滚。
通过以上修改,你可以确保在事务过程中正确地处理错误并执行回滚操作。
根据你提供的代码片段,你的MySQL事务确实存在一些问题。主要问题包括SQL语法错误(例如sekect
应该是select
)以及一些逻辑上的不足。下面是修复后的示例代码,以及如何正确使用事务回滚的方法。
示例代码
const mysql = require('mysql');
const connection = mysql.createConnection({
host: 'localhost',
user: 'yourusername',
password: 'yourpassword',
database: 'yourdatabase'
});
connection.connect();
connection.beginTransaction(function (err) {
if (err) {
return handleError(res, err);
}
const delete_sql = "DELETE FROM tp_lbs WHERE type=?";
connection.query(delete_sql, [type], function (err, result) {
if (err) {
return handleRollback(connection, res, err);
}
const select_sql = "SELECT name FROM tp_lbs WHERE type=?";
connection.query(select_sql, [type], function (err, result) {
if (err) {
return handleRollback(connection, res, err);
}
connection.commit(function (err) {
if (err) {
return handleRollback(connection, res, err);
}
res.json({
success: true,
data: result
});
});
});
});
});
function handleRollback(connection, res, err) {
connection.rollback(function () {
res.json({
success: false,
err: err
});
});
}
function handleError(res, err) {
console.error("Transaction error:", err);
res.json({
success: false,
err: err
});
}
关键点解释
- 连接初始化:确保连接正确初始化并能正常工作。
- 事务开始:使用
beginTransaction
开始一个事务。 - 查询与回滚:
- 每次执行查询后检查是否有错误。如果有,则调用
handleRollback
函数来执行回滚操作。 handleRollback
函数中,使用rollback
方法撤销事务中的所有更改,并返回错误信息给客户端。
- 每次执行查询后检查是否有错误。如果有,则调用
- 提交事务:如果所有查询都成功执行,则调用
commit
方法完成事务。
通过这种方式,可以确保在出现任何错误时,事务会被正确地回滚,从而保持数据库的一致性。