微信登录

数据库事务 - 事务处理 - 在 Node.js 中处理事务

数据库事务 - 事务处理 - 在 Node.js 中处理事务

一、什么是数据库事务

在数据库操作中,事务是一组不可分割的 SQL 操作序列,这些操作要么全部成功执行,要么全部不执行。事务具有四个重要的特性,通常简称为 ACID:

  • 原子性(Atomicity):事务是一个不可分割的工作单位,事务中的操作要么全部成功,要么全部失败回滚。
  • 一致性(Consistency):事务执行前后,数据库的状态必须保持一致。即数据的完整性约束不会被破坏。
  • 隔离性(Isolation):多个事务并发执行时,一个事务的执行不应该影响其他事务的执行,每个事务都感觉不到其他事务的存在。
  • 持久性(Durability):一旦事务提交成功,它对数据库的改变就是永久性的,即使数据库发生故障也不会丢失。

二、为什么需要事务处理

在实际应用中,很多业务场景需要保证数据的一致性和完整性,例如银行转账操作。假设用户 A 向用户 B 转账 100 元,这个操作涉及到两个步骤:从用户 A 的账户扣除 100 元,向用户 B 的账户增加 100 元。如果在扣除用户 A 的账户余额后,系统突然出现故障,而用户 B 的账户没有增加相应的金额,就会导致数据不一致。使用事务可以保证这两个操作要么全部成功,要么全部失败,从而避免数据不一致的问题。

三、在 Node.js 中处理事务

下面以 MySQL 数据库为例,介绍如何在 Node.js 中处理事务。

3.1 安装依赖

首先,确保你已经安装了 Node.js 和 MySQL 数据库。然后,使用以下命令安装 mysql2 模块:

  1. npm install mysql2

3.2 示例代码

  1. const mysql = require('mysql2/promise');
  2. async function transferMoney() {
  3. // 创建数据库连接池
  4. const pool = mysql.createPool({
  5. host: 'localhost',
  6. user: 'your_username',
  7. password: 'your_password',
  8. database: 'your_database',
  9. waitForConnections: true,
  10. connectionLimit: 10,
  11. queueLimit: 0
  12. });
  13. let connection;
  14. try {
  15. // 获取数据库连接
  16. connection = await pool.getConnection();
  17. // 开始事务
  18. await connection.beginTransaction();
  19. // 模拟从用户 A 的账户扣除 100 元
  20. const deductSql = 'UPDATE accounts SET balance = balance - 100 WHERE account_id = 1';
  21. await connection.execute(deductSql);
  22. // 模拟向用户 B 的账户增加 100 元
  23. const addSql = 'UPDATE accounts SET balance = balance + 100 WHERE account_id = 2';
  24. await connection.execute(addSql);
  25. // 提交事务
  26. await connection.commit();
  27. console.log('转账成功');
  28. } catch (error) {
  29. // 发生错误,回滚事务
  30. if (connection) {
  31. await connection.rollback();
  32. }
  33. console.error('转账失败:', error.message);
  34. } finally {
  35. // 释放数据库连接
  36. if (connection) {
  37. connection.release();
  38. }
  39. }
  40. }
  41. // 调用转账函数
  42. transferMoney();

3.3 代码解释

  1. 创建数据库连接池:使用 mysql2/promise 模块创建一个数据库连接池,提高数据库连接的性能。
  2. 开始事务:通过 connection.beginTransaction() 方法开始一个事务。
  3. 执行 SQL 操作:在事务中执行一系列的 SQL 操作,例如扣除用户 A 的账户余额和增加用户 B 的账户余额。
  4. 提交事务:如果所有的 SQL 操作都成功执行,使用 connection.commit() 方法提交事务。
  5. 回滚事务:如果在事务执行过程中发生错误,使用 connection.rollback() 方法回滚事务,将数据库状态恢复到事务开始前的状态。
  6. 释放数据库连接:无论事务执行成功还是失败,最后都要释放数据库连接,避免资源泄漏。

四、总结

步骤 操作 代码示例
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 中安全、可靠地处理数据库事务,保证数据的一致性和完整性。在实际应用中,需要根据具体的业务场景和数据库类型进行适当的调整。

数据库事务 - 事务处理 - 在 Node.js 中处理事务