使用数据库事务
120021、背景
在数据库中,事务是指一系列数据库操作被看作一个单独的执行单元。事务的目标是保证数据库的一致性和完整性,即使在发生错误或中断的情况下也能够恢复到数据库之前的状态。事务通常应用于需要保证多个数据库操作的原子性的场景。
- 什么情况下需要用到事务
多步骤的业务操作:
当一个业务操作需要执行多个步骤,要么全部成功,要么全部失败时,可以使用事务。例如,银行转账操作涉及从一个账户减少金额、另一个账户增加金额,这两步骤要么都执行成功,要么都不执行。确保数据完整性:
当多个数据操作之间存在依赖关系,需要保证数据的完整性时,可以使用事务。例如,在订单系统中,同时更新订单信息和库存信息,需要保证两者的操作要么都成功,要么都失败。防止并发问题:
在多用户并发访问数据库的情况下,可能出现数据竞争和一致性问题。事务可以提供锁定机制,确保在一个事务执行过程中其他事务不能对相同的数据进行修改。
2、特性
事务的特性
原子性(Atomicity): 事务是一个原子操作,要么全部执行成功,要么全部失败回滚。
一致性(Consistency): 事务的执行使数据库从一个一致性状态变到另一个一致性状态。
隔离性(Isolation): 并发事务的执行互不干扰,每个事务在执行过程中看到的数据是独立的。
持久性(Durability): 一旦事务提交,其修改将永久保存在数据库中。
事务解决的问题
数据一致性问题: 保证了多个操作的原子性,防止因为部分操作成功或失败导致的数据不一致问题。
并发问题: 通过事务的隔离性,防止多个事务并发执行时引发的数据竞争和一致性问题
3、示例
两个学生记录将被插入到名为 student 的数据库表中。如果这两个插入操作都成功执行,如果其中任何一个插入操作失败,整个事务将被回滚,确保数据库的一致性。这种方式可以保证这两个插入操作要么同时成功,要么同时失败,从而维护数据库的完整性。
await jianghuKnex.transaction(async trx => {
await trx('student').insert({ name: 'xxx1' });
await trx('student').insert({ name: 'xxx2' });
});
如何使用数据库事务
在大多数关系型数据库中,事务的使用通常涉及以下步骤:
1.启动事务: 通过执行 BEGIN TRANSACTION 或类似的语句来启动一个新事务。
执行事务操作: 在事务中执行一系列数据库操作,包括数据的增删改查。
提交事务: 通过执行 COMMIT 语句,将事务的修改永久保存到数据库中。
回滚事务: 在事务执行过程中发生错误或其他不可预测的情况时,可以执行 ROLLBACK 语句来撤销事务的所有修改。
具体的语法和操作可能因数据库系统而异,上述示例中的 SQL 语句是通用的,实际使用时需要根据具体的数据库系统进行调整。