js实现事务
事务的基本概念
事务是指一组操作要么全部成功,要么全部失败回滚的机制。在JavaScript中,事务通常用于数据库操作或需要原子性执行的业务逻辑。
使用数据库事务(以MySQL为例)
在Node.js中操作MySQL数据库时,可以通过连接对象的beginTransaction、commit和rollback方法实现事务。

const mysql = require('mysql');
const connection = mysql.createConnection({/* 配置 */});
connection.beginTransaction(err => {
if (err) throw err;
connection.query('UPDATE accounts SET balance = balance - 100 WHERE id = 1', (err, result) => {
if (err) {
return connection.rollback(() => {
throw err;
});
}
connection.query('UPDATE accounts SET balance = balance + 100 WHERE id = 2', (err, result) => {
if (err) {
return connection.rollback(() => {
throw err;
});
}
connection.commit(err => {
if (err) {
return connection.rollback(() => {
throw err;
});
}
console.log('事务执行成功');
});
});
});
});
使用MongoDB事务
MongoDB 4.0+支持多文档事务,可以通过以下方式实现:

const { MongoClient } = require('mongodb');
const client = new MongoClient('mongodb://localhost:27017');
async function runTransaction() {
const session = client.startSession();
try {
await session.withTransaction(async () => {
const accounts = client.db('test').collection('accounts');
await accounts.updateOne({ id: 1 }, { $inc: { balance: -100 } }, { session });
await accounts.updateOne({ id: 2 }, { $inc: { balance: 100 } }, { session });
});
} finally {
await session.endSession();
}
}
实现自定义事务逻辑
对于非数据库操作,可以手动实现事务模式:
class Transaction {
constructor() {
this.operations = [];
this.rollbackOperations = [];
}
add(execute, rollback) {
this.operations.push(execute);
this.rollbackOperations.unshift(rollback);
}
async execute() {
try {
for (const op of this.operations) {
await op();
}
} catch (error) {
for (const rollbackOp of this.rollbackOperations) {
await rollbackOp();
}
throw error;
}
}
}
// 使用示例
const transaction = new Transaction();
transaction.add(
() => updateAccount1(),
() => rollbackAccount1()
);
transaction.add(
() => updateAccount2(),
() => rollbackAccount2()
);
transaction.execute().catch(console.error);
使用Promise实现简单事务
对于简单的异步操作,可以使用Promise链实现事务效果:
let account1Updated = false;
let account2Updated = false;
updateAccount1()
.then(() => {
account1Updated = true;
return updateAccount2();
})
.then(() => {
account2Updated = true;
console.log('事务完成');
})
.catch(err => {
if (account1Updated && !account2Updated) {
rollbackAccount1();
}
console.error('事务失败', err);
});
注意事项
数据库事务的具体实现方式取决于使用的数据库驱动和版本。事务操作会带来性能开销,应仅在必要时使用。对于复杂的业务逻辑,可以考虑使用事务脚本模式或领域驱动设计来管理事务边界。






