在数据库操作中,事务是一组不可分割的 SQL 操作序列,这些操作要么全部成功执行,要么全部不执行。事务具有四个重要的特性,通常简称为 ACID:
在实际应用中,很多业务场景需要保证数据的一致性和完整性,例如银行转账操作。假设用户 A 向用户 B 转账 100 元,这个操作涉及到两个步骤:从用户 A 的账户扣除 100 元,向用户 B 的账户增加 100 元。如果在扣除用户 A 的账户余额后,系统突然出现故障,而用户 B 的账户没有增加相应的金额,就会导致数据不一致。使用事务可以保证这两个操作要么全部成功,要么全部失败,从而避免数据不一致的问题。
下面以 MySQL 数据库为例,介绍如何在 Node.js 中处理事务。
首先,确保你已经安装了 Node.js 和 MySQL 数据库。然后,使用以下命令安装 mysql2
模块:
npm install mysql2
const mysql = require('mysql2/promise');
async function transferMoney() {
// 创建数据库连接池
const pool = mysql.createPool({
host: 'localhost',
user: 'your_username',
password: 'your_password',
database: 'your_database',
waitForConnections: true,
connectionLimit: 10,
queueLimit: 0
});
let connection;
try {
// 获取数据库连接
connection = await pool.getConnection();
// 开始事务
await connection.beginTransaction();
// 模拟从用户 A 的账户扣除 100 元
const deductSql = 'UPDATE accounts SET balance = balance - 100 WHERE account_id = 1';
await connection.execute(deductSql);
// 模拟向用户 B 的账户增加 100 元
const addSql = 'UPDATE accounts SET balance = balance + 100 WHERE account_id = 2';
await connection.execute(addSql);
// 提交事务
await connection.commit();
console.log('转账成功');
} catch (error) {
// 发生错误,回滚事务
if (connection) {
await connection.rollback();
}
console.error('转账失败:', error.message);
} finally {
// 释放数据库连接
if (connection) {
connection.release();
}
}
}
// 调用转账函数
transferMoney();
mysql2/promise
模块创建一个数据库连接池,提高数据库连接的性能。connection.beginTransaction()
方法开始一个事务。connection.commit()
方法提交事务。connection.rollback()
方法回滚事务,将数据库状态恢复到事务开始前的状态。步骤 | 操作 | 代码示例 |
---|---|---|
1 | 创建数据库连接池 | const pool = mysql.createPool({...}) |
2 | 获取数据库连接 | connection = await pool.getConnection() |
3 | 开始事务 | await connection.beginTransaction() |
4 | 执行 SQL 操作 | await connection.execute(sql) |
5 | 提交事务 | await connection.commit() |
6 | 回滚事务 | await connection.rollback() |
7 | 释放数据库连接 | connection.release() |
通过以上步骤,我们可以在 Node.js 中安全、可靠地处理数据库事务,保证数据的一致性和完整性。在实际应用中,需要根据具体的业务场景和数据库类型进行适当的调整。