MySQL-事务

4 篇文章 0 订阅
3 篇文章 0 订阅
本文详细介绍了MySQL中的事务特性,包括ACID原则、四种隔离级别(未提交读、提交读、可重复读、可串行化)及其应用场景,以及死锁的概念和事务日志的作用。MySQL默认的隔离级别为可重复读,并通过多版本并发控制解决幻读问题。此外,还讨论了事务可能导致的死锁问题和解决策略。
摘要由CSDN通过智能技术生成

MySQL采用的是自动提交事务的模式。
如果不是非显式的开始一个事务,那么每个查询都当作一个事务执行提交操作。
可以通过设置autcommit来开启或者关闭自动提交

1.事务需要满足的条件:ACID

ACID表示原子性(atomicity),一致性(consistency),隔离性(isolation)和持久性(durability)

  • 原子性:事务内的整个操作要么全部成功,要么失败回滚,不可能只执行其中的一部分操作。
  • 一致性:事务提交前后必须保证数据是完全按照预想的规则进行修改的
  • 隔离性:各个事务之间必须是相互隔离的,防止事务之间修改后导致数据的不一致
  • 持久性:只要事务提交成功,那么数据就会永久的保存到数据库中,即便系统故障也不会丢失

2.隔离级别

2.1未提交读 read uncommitted

在这个隔离级别下,事务之间是相互可见的,也就是事务A可以读取到事务B的数据,但是当事务B发生问题回滚后,事务A就相当于读取到了一个不存在的数据。这种情况也成为脏读,除非有非常特殊的理由需要这样做,实际中都很少使用

2.2提交读(不可重复读 ) read committed

这个隔离级别下,事务之间是不可见的,一个事务只能读到另一个事务已提交的数据,也就是在一个事务开始后到结束前的操作,其他线程都是不可见的。
如果A事务读了一条数据,被B事务修改后并提交了事务,此时A事务还未完成并再次读取这条数据,那读到的会是B事务修改后的数据。

大部分数据库的默认级别都是该级别,但是 mysql不是

2.3可重复读 repeatable read

该级别保证了一个事务在多次读取的记录都是一致的,当A事务读了一条数据后,B事务对此条数据进行了修改并提交了事务,此时A事务还未完成并再次读取这条数据,那它读到的还是A事务一开始读到的数据(通过快照读实现)。但是还是无法解决另一个幻读的问题,也就是当A事务在读取某个范围内的数据时,B事务在这个范围内插入了新的数据,此时A事务再次读取的时候,就会产生幻行InnoDB 和 XtraDB 存储引擎通过多版本并发控制( MVCC,MultiversionConcurrencyControl)解决了幻读的问题。

可重复读是MySQL的默认隔离级别

2.3可串行化 serializable

该级别是最高隔离级别,它强制让事务串行执行,避免了幻读的问题。因为它会在读取的每一行数据上都加锁,所以可能导致大量的超时和锁争抢的问题。实际中也很少用到这个隔离级别,除非是必须保证数据强一致性,并不在乎性能的情况下(也就是串行化损失了并发)使用

3.死锁

在处理并发情况下,产生了两种锁–读锁和写锁。

  • 读锁:读锁是共享的,可让多个事务共同读取其中的数据
  • 写锁:是相互排斥的,只有一个事务写完才会允许另一个事务修改。

因此,当两个事务同时执行了一个update语句时,进行下一个update语句时候凑巧发现他们将要修改的都是对方前一句修改的内容,那么这个时候A事务等待B事务释放锁,而B事务等待A事务释放锁,就会陷入死循环,这就是死锁,必须有外部因素接入,才会打破这种情况。死锁会导致查询非常慢的情况,每个存储引擎解决死锁的方式不一样,一般来说是回滚其中的一个事务。

4.事务日志

事务日志可以帮助提高事务的效率(因为写日志时在磁盘上的一小块区域内进行的顺序IO,比随机IO快的多),使用事务日志的话,当存储引擎在修改表数据的时候,不会去直接写入磁盘,会把事务运行的语句写到日志文件中,然后再刷到磁盘。
所以在事务引擎上的每一次写操作都有两步:

  1. 写入日志文件中
  2. 再写入数据库文件中

如果已经记录到日志中还没有到数据库文件中,这时候发生了系统崩溃,在储存引擎重启时会自动恢复这部分修改的数据。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值