数据库事务的并发和隔离级别

事务

执行某一任务之前,先要给当前状态一个快照(保存了数据库的当前所有状态),然后再具体执行某一系列操作。



事务的基本要素:

1、原子性:事务开始执行的过程中,所有的操作要么全部做完,要么全部都不做,事务执行的过程中出错,就会回滚到事务开始前的状态,事务就是一个不可分割的整体。

2、一致性:当多个事务共同操作数据库的时候,各个事务读取的数据应该都是一致的。

3、隔离性:多个事务并发时,彼此之间的相互影响的程度。

4、持久性:当事务完成提交之后,事务对数据库的所有更新将被保存到数据库中。



事务的并发问题

1、脏读:

  • 事务A读取了事务B正在更新过程中的数据(操作的过程中),然后B回滚操作,那么A读取到的数据是脏数据

  • 脏读就是一个事务A去读另一个事务B的快照内容,因为不确定事务B的操作是否要生效,所以可能会产生脏读的问题。

2、不可重复读:

  • 事务 A 多次读取同一数据,事务 B 在事务A多次读取的过程中,对数据作了更新并提交(操作完成了),导致事务A此时读取同一数据时,和之前读取的结果不一致。
  • 事务A读取的是数据库里面的内容,所以当事务B提交了之后会改变数据库里面的内容,所以会出现事务A两次查询的结果不一致。

3、幻读:

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



事务隔离级别

事务隔离级别脏读不可重复读幻读
读未提交(read-uncommitted)
不可重复读(read-committed)
可重复读(repeatable-read)
串行化(serializable)

mysql默认事务隔离级别是rr



事务的具体操作

1、当一个端口操作开启了事务,另一个端口却未开启事务的时候。

  • 开启事务修改
    在这里插入图片描述

  • 未开启事务查询

在这里插入图片描述

从这里可见,开启事务和未开启事务的查询结果不一致,这是因为开启事务的操作未提交(commit)。


2、修改事务的隔离级别

  • 修改当前连接的隔离级别

    set session transaction_isolation=‘隔离级别’;

    打开事务:

    start transaction;

  • 修改全局的隔离级别


3、读未提交:

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

在这里插入图片描述


(2)打开另一个客户端B,并查询表tb_user:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yO7y1Eo3-1593497560239)(/home/shiruntao/图片/4.png)]


这时,虽然客户端A的事务还没提交,但是客户端B就可以查询到A已经更新的数据,一旦客户端A的事务因为某种原因回滚,所有的操作都将会被撤销,所以此时客户端B查询到的数据其实就是脏数据。

4、读已提交

(1)打开一个客户端A,并设置当前事务模式为read committed(未提交读),查询表tb_user的所有记录,并修username属性值,然后提交:

在这里插入图片描述


(2)客户端B设置隔离级别为rc,客户端B先查询数据库,然后客户端A已经提交,客户端B再继续查询,结果与上一步不一致,即产生了不可重复读的问题

在这里插入图片描述


5、可重复读

(1)打开一个客户端A,并设置当前事务模式为repeatable read,查询表tb_user的所有记录,并修改其中一条记录,并提交。

在这里插入图片描述


(2)重新打开一个客户端B,并设置当前事务模式为repeatable read,查询表tb_user的所有记录,然后等待客户端A修改并提交之后,然后在查询一次。

在这里插入图片描述


可以看出,两次结果一致,并没有出现不可重复读的问题。此时事务B读取的是启动事务的时候产生自己的快照,所以当事务A提交了之后就算会改变数据库里面的内容,也不会影响事务B的查询结果。


4.串行化

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

在这里插入图片描述


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

在这里插入图片描述  



注意
  • 事务隔离级别为读提交时,写数据只会锁住相应的行
  • 事务隔离级别为可重复读时,如果检索条件有索引(包括主键索引)的时候,默认加锁方式是next-key锁;如果检索条件没有索引,更新数据时会锁住整张表。一个间隙被事务加了锁,其他事务是不能在这个间隙插入记录的,这样可以防止幻读。
  • 事务隔离级别为串行化时,读写数据都会锁住整张表
  • 隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值