mysql强制提交所有事务_mysql的四种事务隔离级别

本文介绍了MySQL中的事务及其ACID特性,详细讲解了事务的四种隔离级别:读未提交、读已提交、可重复读和串行化,通过实例展示了不同隔离级别下可能出现的并发问题及解决方案。MySQL的默认隔离级别为可重复读。
摘要由CSDN通过智能技术生成

什么是事务

事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所做的所有更改都会被撤消。也就是事务具有原子性,一个事务中的一系列的操作要么全部成功,要么一个都不做。

事务的结束有两种,当事务中的所以步骤全部成功执行时,事务提交。如果其中一个步骤失败,将发生回滚操作,撤消之前到事务开始时的所有操作。

事务的ACID

1、原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做,不可能停滞在中间环节。事务执行过程中出错,会回滚到事务开始前的状态,所有的操作就像没有发生一样。也就是说事务是一个不可分割的整体,就像化学中学过的原子,是物质构成的基本单位。

2、一致性(Consistency):事务开始前和结束后,数据库的完整性约束没有被破坏 。比如A向B转账,不可能A扣了钱,B却没收到。

3、隔离性(Isolation):同一时间,只允许一个事务请求同一数据,并发执行不同的事务之间彼此没有任何干扰。比如A正在从一张银行卡中取钱,在A取钱的过程结束前,B不能向这张卡转账。

4、持久性(Durability):事务完成后,事务对数据库的所有更新将被保存到数据库,其它操作或故障不应该对其执行结果有任何影响,不能回滚。

事务的并发问题

1、脏读:事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到的数据是脏数据

2、不可重复读:事务 A 多次读取同一数据,事务 B 在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果 不一致。

3、幻读:系统管理员A将数据库中所有学生的成绩从具体分数改为ABCDE等级,但是系统管理员B就在这个时候插入了一条具体分数的记录,当系统管理员A改结束后发现还有一条记录没有改过来,就好像发生了幻觉一样,这就叫幻读。

小结:不可重复读的和幻读很容易混淆,不可重复读侧重于修改,幻读侧重于新增或删除。解决不可重复读的问题只需锁住满足条件的行,解决幻读需要锁表

事务隔离级别

1、Read Uncommitted(读取未提交内容)

在该隔离级别,所有事务都可以看到其他未提交事务的执行结果。本隔离级别很少用于实际应用,因为它的性能也不比其他级别好多少。读取未提交的数据,也被称之为脏读(Dirty Read)。

2、Read Committed(读取提交内容)

这是大多数数据库系统的默认隔离级别(但不是MySQL默认的)。它满足了隔离的简单定义:一个事务只能看见已经提交事务所做的改变。这种隔离级别 也支持所谓的不可重复读(Nonrepeatable Read),因为同一事务的其他实例在该实例处理其间可能会有新的commit,所以同一select可能返回不同结果。

3、Repeatable Read(可重读)

这是MySQL的默认事务隔离级别,它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行。不过理论上,这会导致另一个棘手的问题:幻读 (Phantom Read)。简单的说,幻读指当用户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的“幻影” 行。InnoDB和Falcon存储引擎通过多版本并发控制(MVCC,Multiversion Concurrency Control)机制解决了该问题。

4、Serializable(可串行化)

这是最高的隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。简言之,它是在每个读的数据行上加上共享锁。在这个级别,可能导致大量的超时现象和锁竞争。

91a531330bd71d9b4f921d6bff33b057.png

mysql默认的事务隔离级别为repeatable-read

dec6a00b5303cf8d53cf0d9e8f7b4ff2.png

各个隔离级别的情况

CREATE TABLE `account` (

`id` bigint(20) NOT NULL AUTO_INCREMENT,

`name` varchar(11) DEFAULT '',

`balance` decimal(10,2) DEFAULT NULL ,

PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4;

1、读未提交

(1)打开一个客户端A,并设置当前事务模式为read uncommitted(未提交读),查询表account的初始值:

71f89b0355c624821f9e9cbd88c2fc37.png

(2)在客户端A的事务提交之前,打开另一个客户端B,更新表account:

98394dcace107ed694765306aa14d05c.png

(3)这时,虽然客户端B的事务还没提交,但是客户端A就可以查询到B已经更新的数据:

fc112ace6ac89d239a8126354dd5dd57.png

(4)一旦客户端B的事务因为某种原因回滚,所有的操作都将会被撤销,那客户端A查询到的数据其实就是脏数据:

93964a13f2892b2e2784612dda31b4cb.png

(5)在客户端A执行更新语句update account set balance = balance - 50 where id =4,Lucy的balance没有变成200,居然是250,是不是很奇怪,数据不一致啊,如果你这么想就太天真了,在应用程序中,我们会用300-50=250,并不知道其他会话回滚了,要想解决这个问题可以采用读已提交的隔离级别

399a03e8abfb425c5e5aefc6b2ec6bf7.png

2、读已提交

(1)打开一个客户端A,并设置当前事务模式为read committed(已提交读),查询表account的所有记录:

30d6dcd645a6ae579a4df02b8f6afb04.png

(2)在客户端A的事务提交之前,打开另一个客户端B,更新表account:

c2fd90be1636da779322107d80b6bb24.png

(3)这时,客户端B的事务还没提交,客户端A不能查询到B已经更新的数据,解决了脏读问题:

c69702f0fbfa50365877fddf51819f56.png

(4)客户端B的事务提交

5ef185d8149282c564dc7ba3b71cb0b5.png

(5)客户端A执行与上一步相同的查询,结果 与上一步不一致,即产生了不可重复读的问题

8cdc7edc81156aa2d3efd57246a2aba8.png

3、可重复读

(1)打开一个客户端A,并设置当前事务模式为repeatable read,查询表account的所有记录

fc15bfb5628b869f689be5d0c542c8f2.png

(2)在客户端A的事务提交之前,打开另一个客户端B,更新表account并提交

88c2a32cc5c0c9551d8fe9658cdfbb1a.png

(3)在客户端A查询表account的所有记录,与步骤(1)查询结果一致,没有出现不可重复读的问题

f4f7a018ca64b45494afb57cd380c104.png

(4)在客户端A,接着执行update balance = balance - 50 where id = 1,balance没有变成350-50=300,lucy的balance值用的是步骤(2)中的300来算的,所以是250,数据的一致性倒是没有被破坏。可重复读的隔离级别下使用了MVCC机制,select操作不会更新版本号,是快照读(历史版本);insert、update和delete会更新版本号,是当前读(当前版本)。

10576f81cbc2a41b433850c5d2b93dc7.png

(5)重新打开客户端B,插入一条新数据后提交

33f8e218c2491848c64392902383082d.png

(6)在客户端A查询表account的所有记录,没有 查出 新增数据,所以没有出现幻读

332a9d58a6082f7f9dbc2345e95e86e2.png

4、串行化

(1)打开一个客户端A,并设置当前事务模式为serializable,查询表account的初始值:

328b738c9196e3adcd8a83c4fae1b039.png

(2)打开一个客户端B,并设置当前事务模式为serializable,插入一条记录报错,表被锁了插入失败,mysql中事务隔离级别为serializable时会锁表,因此不会出现幻读的情况,这种隔离级别并发性极低,开发中很少会用到。

9fe55796f47c753ec2e8e86a0c742134.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值