《深入解析数据库事务的四大特性与事务隔离级别》
一、数据库事务的四大特性
1、原子性(Atomicity)
图片来源于网络,如有侵权联系删除
- 原子性是指事务是一个不可分割的工作单位,事务中的操作要么全部执行,要么全部不执行,在一个银行转账的事务中,从账户A转出100元到账户B,这个事务包含两个操作:从A账户减100元以及在B账户加100元,如果在执行过程中,从A账户减100元成功了,但是由于某些原因(如系统故障)在给B账户加100元时失败了,根据原子性,整个事务就会回滚,也就是说,A账户的100元不会被扣除,就好像这个转账事务从来没有发生过一样。
- 在数据库系统中,原子性的实现通常依赖于日志(如重做日志和回滚日志),当事务开始执行时,数据库会记录下事务的相关操作信息,如果事务正常提交,重做日志可以用来将事务的更改持久化;如果事务需要回滚,回滚日志可以将数据库状态恢复到事务开始之前的样子。
2、一致性(Consistency)
- 一致性要求事务必须使数据库从一个一致性状态变换到另一个一致性状态,数据库的一致性状态是指数据库中的数据满足所有的完整性约束,例如实体完整性(每个表中的主键唯一)、参照完整性(外键关系正确)等。
- 继续以银行转账为例,在转账之前,整个银行系统的账户余额总和是一个固定值,当执行转账事务时,只要事务是正确执行的,转账后账户余额总和应该仍然保持不变,如果存在违反一致性的操作,比如通过漏洞使得转账金额没有按照正常的规则计算,导致账户余额总和发生错误的变化,那么就破坏了数据库的一致性,数据库管理系统通过各种约束检查机制(如在表定义时设置的列的取值范围、唯一性约束等)和事务的正确执行来确保一致性。
3、隔离性(Isolation)
- 隔离性确保多个事务并发执行时,一个事务的执行不能被其他事务干扰,每个事务都感觉不到有其他事务在并发执行,有两个事务T1和T2同时对同一个账户进行操作,T1是查询账户余额,T2是向该账户存款,如果没有隔离性,T1可能会在T2更新账户余额的过程中读取到一个不一致的值(T2已经更新了部分数据但事务还未提交)。
- 为了实现隔离性,数据库管理系统采用了不同的并发控制机制,常见的有锁机制(如共享锁和排他锁)和多版本并发控制(MVCC),锁机制通过对数据对象加锁来限制其他事务的访问,而MVCC则通过维护数据的多个版本来实现并发事务之间的隔离。
图片来源于网络,如有侵权联系删除
4、持久性(Durability)
- 持久性表示一旦事务提交,它对数据库中数据的改变就应该是永久性的,即使系统发生故障(如断电、磁盘损坏等),这些修改也不会丢失,当一个事务成功将一条新的订单记录插入到数据库的订单表中并提交后,即使数据库服务器突然断电重启,这条新插入的订单记录仍然应该存在于数据库中。
- 数据库通过将事务的更改写入到磁盘等持久化存储介质来实现持久性,这通常涉及到数据库的缓存管理和写磁盘策略,数据库系统会在合适的时机将内存中的数据更改刷写到磁盘上,以确保数据的持久性。
二、事务隔离级别
1、读未提交(Read Uncommitted)
- 这是最低的隔离级别,在这个级别下,一个事务可以读取到另一个未提交事务的数据修改,这种情况可能会导致脏读(Dirty Read)问题,事务T1修改了一个数据项的值但尚未提交,事务T2在这个时候读取了这个被T1修改的值,如果T1后来回滚了,那么T2读取到的数据就是无效的(脏数据),这种隔离级别虽然并发性能较高,但是数据的一致性和准确性难以保证,所以在实际的生产环境中很少使用。
2、读已提交(Read Committed)
- 在这个隔离级别下,一个事务只能读取到已经提交的事务的数据修改,可以避免脏读问题,它可能会导致不可重复读(Non - Repeatable Read)问题,事务T1在某个时刻读取了一个数据项的值,然后事务T2修改并提交了这个数据项的值,当T1再次读取这个数据项时,得到的值与第一次读取的值不同,在很多数据库应用场景中,如一些对数据准确性要求较高的报表查询场景,这种不可重复读可能会带来问题。
图片来源于网络,如有侵权联系删除
3、可重复读(Repeatable Read)
- 可重复读隔离级别确保在同一个事务中多次读取同一数据项时,得到的值是相同的,它通过在事务开始时创建数据的快照或者使用锁机制来实现,这个级别可能会出现幻读(Phantom Read)问题,事务T1在执行查询操作时,根据某个条件查询到了一组数据,然后事务T2插入了一条满足T1查询条件的新数据并提交,当T1再次执行相同的查询操作时,会发现多了一条之前没有的记录,就好像出现了“幻影”一样。
4、串行化(Serializable)
- 这是最高的事务隔离级别,在串行化隔离级别下,事务是串行执行的,就好像每个事务是一个接一个地执行,不存在并发执行的情况,这样可以完全避免脏读、不可重复读和幻读问题,这种隔离级别的并发性能最差,因为它严重限制了事务的并发执行能力,在对数据一致性要求极高、并发操作较少的场景下可以使用,例如一些对财务数据进行年终结算的场景。
不同的事务隔离级别在并发性能和数据一致性之间进行了不同程度的权衡,数据库开发人员需要根据具体的应用需求,选择合适的事务隔离级别来确保数据的正确性和系统的性能,在一个高并发的电商系统中,如果对数据的准确性要求不是特别高(如商品的浏览量统计),可以选择读已提交隔离级别;而对于订单处理等涉及资金和关键业务数据的事务,可能需要选择可重复读或者串行化隔离级别。
评论列表