什么是事务?
在数据库中,事务是指作为单个逻辑工作单元执行的一系列操作。通常,一个事务包括一组数据库操作语句,这些语句构成了一个逻辑单元,要么都执行要么都不执行。事务是一种保证数据完整性并支持数据一致性的机制。当多个用户同时访问数据库时,使用事务能够防止数据的冲突和不一致。
Sequelize 中的事务处理
Sequelize 是一个基于 Node.js 的 ORM(对象关系映射)框架,它支持多种数据库。在 Sequelize 中,使用事务可以确保在多个数据库操作的过程中,只有当所有操作都成功完成时,才会将这些操作提交到数据库中。
开启事务
在 Sequelize 中,使用 transaction 方法来开启一个事务。这个方法返回一个 Promise 对象,我们可以在 Promise 的回调函数中进行数据库操作。下面是一个示例:
-- -------------------- ---- -------
----- -- - ----------------
----- - --------- - - ---
---------
---------------- -- -
-- -----------------
------ -------------
-- --------------------- - -----
---------------- ----- ----- -- - ------ - --- - -- ------------ - ---
----------------- ----- ----- -- - ------------ - ---
---
--
-------- -- -
----------------------
--
-------------- -- -
------------------------ -------
---在上面的示例中,我们首先使用 db 模块中的 sequelize 对象来获取 Sequelize 实例,并调用 transaction 方法开启一个事务。在事务的回调函数中,我们执行了两个数据库操作:更新 User 表中 id 为 1 的用户的名称,并在 Order 表中创建一条新的订单。这两个操作都通过设置 transaction 参数来告诉 Sequelize 这是在这个事务中执行的操作。
注意,在回调函数中我们需要将这些操作封装在一个 Promise 对象中,并返回这个 Promise 对象。这样做是为了确保所有操作执行完毕后,事务才会提交。如果在回调函数中抛出了异常或者返回了一个被拒绝的 Promise,那么事务就会被回滚,所有操作都会被撤销。如果所有操作都成功完成,那么事务就会被提交。
回滚事务
在上面的示例中,我们使用了 Promise 的 catch 方法来处理事务提交失败的情况。在这个示例中,如果任何一个数据库操作失败了,那么整个事务都会被回滚,所有操作都会被撤销。如果我们需要手动回滚事务,可以在回调函数中抛出一个异常即可:
-- -------------------- ---- -------
---------
---------------- -- -
-- -----------------
----- --- ----------------
--
-------- -- -
----------------------
--
-------------- -- -
------------------------ -------
---在这个示例中,我们直接抛出了一个异常来回滚事务。当事务回滚时,所有操作都会被撤销并抛出异常。
并发事务
在某些情况下,同时执行多个事务可能是必要的。在 Sequelize 中,我们可以使用 Sequelize.Transaction.ISOLATION_LEVELS 枚举类型来指定事务的隔离级别和锁定策略。隔离级别包括:READ_UNCOMMITTED、READ_COMMITTED、REPEATABLE_READ 和 SERIALIZABLE。锁定策略包括:SHARED 和 EXCLUSIVE。默认情况下,隔离级别为 REPEATABLE_READ,锁定策略为 SHARED。
下面是一个并发事务的示例:
-- -------------------- ---- -------
---------
-------------- --------------- --------------------------------------------------- -- ----- --- -- -
-- -----------------
----- ---------------- ----- ----- -- - ------ - --- - -- ------------ - ---
-- -----------
----- --- ----------------- -- ------------- -- ---------- -------
----- ----------------- ----- ----- -- - ------------ - ---
--
-------- -- -
----------------------
--
-------------- -- -
------------------------ -------
---在这个示例中,我们使用 transaction 方法的第一个参数来设置隔离级别和锁定策略。我们还使用了 async/await 特性来模拟一个耗时的操作。由于设置了 SERIALIZABLE 隔离级别,所以这两个事务是串行执行的,后一个事务必须等到前一个事务执行完毕才能开始执行。
总结
使用事务可以确保数据库操作的原子性和一致性,是开发 Web 应用程序时不可或缺的机制。在 Sequelize 中,我们可以使用 transaction 方法来开启事务,使用 Promise 特性来执行数据库操作,并使用异常处理来回滚事务。通过设置隔离级别和锁定策略,我们还可以实现并发事务。
Source: FunTeaLearn,Please indicate the source for reprints https://funteas.com/post/64546bd7968c7c53b0852c39