事务及隔离机制

本文详细阐述了数据库事务中的脏读、不可重复读和幻读现象,并介绍了四种事务隔离级别:读未提交、读已提交、可重复读和序列化,通过示例展示了不同隔离级别下的行为,旨在帮助理解事务处理中的数据一致性问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

脏读: 当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。

不可重复读: 是指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的的数据可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。(对数据的修改(更新))

幻读:第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样。(对数据的插入与删除)

  • 可重复读会导致出现幻读,但如果使用普通的读,会得到一直性的结果。如果使用了加锁的读,就会读到最新的提交结果 

 

数据库事务隔离级别

  •   Read UnCommitted(读未提交):最低的隔离级别。一个事务可以读取另一个事务并未提交的更新结果。

  • Read Committed(读提交):一个事务的更新操作结果只有在该事务提交之后,另一个事务才可以的读取到同一笔数据更新后的结果。

  • Repeatable Read(重复读):mysql的默认级别。整个事务过程中,对同一笔数据的读取结果是相同的,不管其他事务是否在对共享数据进行更新,也不管更新提交与否。

  •  Serializable(序列化):最高隔离级别。所有事务操作依次顺序执行。注意这会导致并发度下降,性能最差。通常会用其他并发级别加上相应的并发锁机制来取代它。该级别可以防止脏读、不可重复读以及幻读。但是这将严重影响程序的性能。通常情况下也不会用到该级别。

 

 

示例

数据库表users的基本信息

 

以读未提交(read-uncommitted)举例,其他同理

 出现了脏读,session2的第五步读取了session1还未提交的数据,当session1回滚时,此时session读的的数据是无效的。

 

参考文献

1.MySQL 四种事务隔离级的说明

2.MySQL事务隔离级别测试实例

3.数据库事务隔离级别 - 分析脏读 & 不可重复读 & 幻读

MySQL的事务隔离机制是通过不同的隔离级别来控制事务并发执行时的数据可见性和一致性。隔离级别越高,事务之间的隔离程度越好,但性能开销也越大。SQL标准定义了四种常见的事务隔离级别,MySQL也支持这四种级别,并且每种级别都有其特定的实现原理。 ### 事务隔离级别 MySQL支持以下四种事务隔离级别: 1. **未提交读(Read Uncommitted)**:这是最低的隔离级别,允许一个事务读取另一个事务未提交的数据。这种级别可能导致脏读(Dirty Read),即读取到无效的或未提交的数据。 2. **提交读(Read Committed)**:该级别确保一个事务只能读取到其他事务已经提交的数据。它避免了脏读,但可能会出现不可重复读(Nonrepeatable Read)和幻读(Phantom Read)。 3. **可重复读(Repeatable Read)**:这是MySQL的默认隔离级别。它确保在同一个事务中多次读取同一数据时,结果是一致的,即使其他事务对数据进行了修改并提交。可重复读级别解决了不可重复读的问题,但可能仍然存在幻读。 4. **串行化(Serializable)**:这是最高的隔离级别,通过强制事务串行执行来避免所有并发问题。它完全隔离了事务之间的数据访问,避免了脏读、不可重复读和幻读,但性能开销最大。 ### 实现原理 MySQL的事务隔离机制主要依赖于其存储引擎(如InnoDB)来实现。InnoDB通过多版本并发控制(MVCC)和锁机制来实现不同级别的隔离性。 - **一致性读(Consistent Read)**:InnoDB使用多版本并发控制(MVCC)来提供一致性读。在`REPEATABLE READ`隔离级别下,事务中的所有一致性读都读取事务开始时的快照。而在`READ COMMITTED`隔离级别下,事务中的每个一致性读都会读取最新的快照版本。一致性读不会对表加锁,因此多个事务可以并发地修改数据。 - **锁机制**:InnoDB支持行级锁和表级锁。在`READ COMMITTED`和`REPEATABLE READ`级别,InnoDB使用行级锁来控制并发访问。在`SERIALIZABLE`级别,InnoDB会对所有读取操作加锁,从而强制事务串行化执行。 - **不可重复读与幻读**:在`READ COMMITTED`级别,由于每次一致性读都会刷新快照,因此可能会出现不可重复读。而在`REPEATABLE READ`级别,事务在整个生命周期内使用同一个快照,因此避免了不可重复读。至于幻读,在`REPEATABLE READ`级别,InnoDB通过间隙锁(Gap Lock)来防止其他事务插入新行,从而避免了幻读。 ### 隔离级别与并发问题的关系 | 隔离级别 | 脏读 | 不可重复读 | 幻读 | 丢失更新 | |---------------------|------|------------|------|----------| | 未提交读(Read Uncommitted) | 可能 | 可能 | 可能 | 可能 | | 提交读(Read Committed) | 不可能 | 可能 | 可能 | 可能 | | 可重复读(Repeatable Read) | 不可能 | 不可能 | 不可能 | 可能 | | 串行化(Serializable) | 不可能 | 不可能 | 不可能 | 不可能 | ### 设置隔离级别 在MySQL中,可以通过以下命令设置事务隔离级别: ```sql SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE}; ``` 例如,将当前会话的隔离级别设置为`READ COMMITTED`: ```sql SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; ``` ### 总结 MySQL的事务隔离机制通过不同的隔离级别和实现原理来平衡数据一致性和并发性能。选择合适的隔离级别取决于具体的应用场景和对数据一致性的要求。较高的隔离级别可以提供更强的数据一致性,但可能会降低系统的并发性能[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值