MySQL篇(四)事务相关知识详解

MySQL篇(四)事务相关知识详解

MySQL篇(四)事务相关知识详解

一、事务的特性(ACID)

原子性(Atomicity)

原子性是指事务是一个不可分割的工作单位,事务中的操作要么全部执行,要么全部不执行。比如在银行转账中,从一个账户扣款和向另一个账户存款这两个操作必须同时成功或者同时失败,不能只执行其中一个操作 ,确保了数据的完整性和一致性。

一致性(Consistency)

一致性是指事务执行前后,数据库的完整性约束没有被破坏 。例如转账前后,两个账户的总金额应该保持不变。它关注的是业务逻辑上的正确性,通过原子性、隔离性和持久性来保证。

隔离性(Isolation)

隔离性是指多个事务并发执行时,一个事务的执行不能被其他事务干扰。不同的隔离级别决定了事务之间相互干扰的程度,比如在高并发场景下,多个事务同时操作相同数据时,隔离性可以防止数据出现脏读、不可重复读、幻读等问题。

持久性(Durability)

持久性是指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的,接下来的其他操作或故障不应该对其执行结果有任何影响 。例如转账成功提交事务后,即使系统崩溃,转账的结果依然存在。

二、并发事务带来的问题

脏读(Dirty Read)

一个事务读取到了另一个事务尚未提交的数据。比如事务A修改了某条记录但未提交,此时事务B读取了这条被修改但未提交的记录,如果事务A回滚,事务B读取到的数据就是无效的脏数据。

不可重复读(Non - repeatable Read)

在一个事务内多次读取同一数据时,由于其他事务对该数据进行了修改并提交,导致在本事务中多次读取的数据不一致。例如事务A读取某条记录,然后事务B修改并提交了这条记录,事务A再次读取时得到了不同的值。

幻读(Phantom Read)

在一个事务中执行查询操作,在事务执行过程中,由于其他事务插入了新的数据,当该事务再次执行相同的查询时,结果集发生了变化,就好像产生了"幻影"数据。比如事务A查询符合某条件的记录,事务B插入了符合该条件的新记录并提交,事务A再次查询时就会发现多了一些记录。

三、解决并发事务问题的方法

通过设置不同的事务隔离级别来解决并发事务问题:

读未提交(Read Uncommitted)

最低的隔离级别,允许读取未提交的数据,会导致脏读、不可重复读和幻读问题,一般很少使用。

读已提交(Read Committed)

一个事务只能读取其他事务已经提交的数据。可以避免脏读,但仍然可能出现不可重复读和幻读问题,是大多数数据库的默认隔离级别(MySQL默认不是这个 )。

可重复读(Repeatable Read)

在一个事务内的多次读取操作会返回相同的数据,即使其他事务对数据进行了修改并提交。可以避免脏读和不可重复读,但在某些情况下仍可能存在幻读问题。MySQL的默认隔离级别是可重复读,通过MVCC(多版本并发控制)机制在一定程度上解决了幻读问题。

串行化(Serializable)

最高的隔离级别,事务会按照顺序依次执行,就像单线程环境一样,能避免脏读、不可重复读和幻读的所有问题,但并发性能较差。

四、MySQL的默认隔离级别

MySQL的默认隔离级别是可重复读(Repeatable Read) 。在这种隔离级别下,MySQL通过MVCC机制来实现事务的并发控制。MVCC为每个事务维护一个一致性视图,事务在读取数据时,根据这个视图来判断数据的可见性,从而在保证数据一致性的同时提高并发性能。

五、undo log和redo log的区别

undo log

undo log主要用于事务的回滚操作。当事务执行过程中需要回滚时,undo log可以记录数据修改前的版本信息,通过这些信息将数据恢复到事务开始前的状态。同时,undo log在MVCC机制中也起到重要作用,用于构建一致性视图,提供旧版本数据的可见性判断依据。

redo log

redo log主要用于保障事务的持久性。在事务提交时,先将事务的修改操作记录到redo log中,然后再将数据真正写入磁盘。当数据库发生崩溃恢复时,可以根据redo log中的记录将数据恢复到事务提交后的状态,确保已提交事务的数据不会丢失。

六、MySQL中的MVCC(多版本并发控制)

MVCC是一种用于实现数据库并发控制的机制,它通过为数据库中的每行数据维护多个版本来实现事务的并发执行。在MySQL的InnoDB存储引擎中:

  • 实现原理:MVCC为每行数据记录多个版本,每个版本包含事务ID等信息。当事务读取数据时,根据事务的开始时间戳和数据版本的事务ID来判断数据是否可见。如果数据版本的事务ID小于当前事务的开始时间戳,那么该版本数据对当前事务可见;否则不可见。
  • 作用:MVCC可以在不使用锁(或减少锁的使用)的情况下,实现事务的并发读取,提高了数据库的并发性能,同时在可重复读隔离级别下,配合undo log有效解决了脏读、不可重复读问题,并在一定程度上缓解了幻读问题。
相关推荐
武子康几秒前
Java-27 深入浅出 Spring - 实现简易Ioc-03 在上节的业务下手动实现IoC 从 XML 配置到 BeanFactory 反射注入
java·后端·mybatis
睡不醒男孩0308232 分钟前
生产环境故障销账:PostgreSQL 突发连接数暴涨与死锁,如何利用 CLup 秒级定位与解锁?
运维·数据库
2601_962054954 分钟前
终端与IDE形态的vibe coding实测:两款AI编程工具迭代能力对比
数据库·ide·ai编程
二哈赛车手6 分钟前
新人笔记---idea索引失效问题解决方案
java·笔记·spring·elasticsearch·intellij-idea
万岳科技14 分钟前
教育培训系统开发流程详解:平台建设关键环节解析
数据库·后端·学习
Nturmoils16 分钟前
线上修一批脏数据,先别急着全量重来
数据库·后端
吴声子夜歌18 分钟前
SQL经典实例——处理字符串
数据库·sql
飞天狗11120 分钟前
零基础JavaWeb入门——第五课第一小节:九大内置对象 · 第1个:request(请求对象)
java·开发语言·前端·后端·servlet
a151084169331 分钟前
记一次大模型探索
java·服务器·前端
c++之路37 分钟前
Bazel C++ 构建系列文档(五):多目标与多包项目
java·开发语言·c++