《数据库》MySQL四种事务隔离级别

事务的定义

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

四大特性

数据库事务transancion正确执行的基本要素。ACID,原子性(Atomicity)、一致性(correspondence)、隔离性(Isolation)、持久性(Durability)。

  1. 原子性:整个事务中的所有操作,要么全部完成,要么全部不完成,不可能停滞在中间的某个环节。事务在执行的过程中发生错误,会被回滚(Rollback)到事务开始前的状态,像这个事务从来没有执行过一样。
  2. 一致性:在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏。
  3. 隔离性:隔离状态执行事务,使他们好像是系统在给定时间内执行的唯一操作。如果有两个事务,运行在相同的时间内,执行相同的功能,事务的隔离性将确保每一事务在系统中认为只有该事务在使用系统。这种属性有时称为串行化,为防止事务操作间的混淆,必须串行化或者序列化请求,使得在同一时间仅有一个请求用于同一数据。
  4. 持久性:在事务完成以后,改事务对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。

不考虑隔离性引发的安全性问题

  1. 脏读:一个事务读到了另一个事务未提交的数据。
  2. 不可重复读:一个事务读到另一个事务已经提交的update的数据导致多次查询结果不一致
  3. 虚幻读:一个事务读到了另一个事务已经提交的insert的数据导致多次查询结果不一致。

五种隔离级别

隔离级别是指若干个并发的事务之间的隔离程度。为解决上述读问题,设置事务的5种隔离级别:

  1. DEFAULT这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别;
  2. 未提交读(read uncommited):脏读,不可重复读,虚读都有可能发生
  3. 已提交读(read commited):避免脏读。但是不可重复读和虚读都有可能发生;
  4. 可重复读(repeatable read):避免脏读和不可重复读,但是虚读有可能发生;
  5. 串行化的(serializable):避免以上所有读问题。这是花费最高代价但最可靠但事务隔离级别。

不可重复读和幻读比较:

  • 两者有些相似,但是前者针对的是update或delete,后者针对的insert。

数据库sql设置隔离级别:

  • MySQL默认:可重复读
  • Oracle默认:已提交读
脏读不可重复读幻读
未提交读read uncommitedVVV
已提交读read commitedXVV
可重复读repeatable readXXV
串行化 serializableXXV

事务并发时存在的问题:

  1. 脏读(Dirty Read)
    脏数据所指的就是未提交的数据,而脏读是指在一个事务处理过程里读取了另一个未提交的事务中的数据。比如,一个事务正在对一条记录做修改,在这个事务完成并提交之前,这条数据是处于待定状态的(可能提交也可能回滚),这时,第二个事务来读取这条没有提交的数据,并据此做进一步的处理,就会产生未提交的数据依赖关系。这种现象被称为脏读。

  2. 不可重复读(Non-repeatable Read)
    一个事务先后读取同一条记录,而事务在两次读取之间该数据被其它事务所修改,则两次读取的数据不同,我们称之为不可重复读。例如事务T1在读取某一数据,而事务T2立马修改了这个数据并且提交事务给数据库,事务T1再次读取该数据就得到了不同的结果,发送了不可重复读。

  3. 幻读(Phantom Read)
    一个事务按相同的查询条件重新读取以前检索过的数据,却发现其他事务插入了满足其查询条件的新数据,这种现象就称为幻读。幻读是指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,比如这种修改涉及到表中的“全部数据行”。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入“一行新数据”。那么,以后就会发生操作第一个事务的用户发现表中还存在没有修改的数据行,就好象发生了幻觉一样。

不可重复读和脏读的区别:脏读是某一事务读取了另一个事务未提交的脏数据,而不可重复读则是在同一事务内读取了前一事务提交的数据,即前一次读到的数据是另一个事务提交前,后一次读到的数据是提交后的。
幻读和不可重复读都是读取了另一条已经提交的事务(这点就脏读不同),所不同的是不可重复读查询的都是同一个数据项,而幻读针对的是一批数据整体(比如数据的个数)。

在实际开发和使用中,其实幻读问题是可以接受也符合用户的心理预期,比如在淘宝双十一抢东西,点击“购买”,成功进入**“下单页面”,结果到“付款页面”**却提示已经被抢完,这是可以接受的。

表锁和行锁

锁是计算机协调多个进程或线程并发访问某一资源的机制。
在mysql种,锁可以分为:行锁和表锁两种类型,MySAM存储引擎只支持表锁,MEMORY存储引擎只支持表锁,InnoDB:支持表锁也支持行锁。

锁类型开销加锁速度死锁锁定粒度并发性能
表锁不会出现发生锁冲突的概率高,并发度低
行锁会出现发生锁冲突的概率低,并发大高

表锁:适合以查询场景比较多的表。
行锁:适合并发更新比较少的表。
InnoDB行锁是通过给索引上的索引项加索来实现的,行锁只能通过索引条件检索数据的

七种传播行为

Spring中的7个事务传播行为:

事务行为说明
PROPAGATION_REQUIRED支持当前事务,假设当前没有事务。就新建一个事务
PROPAGATION_SUPPORTS支持当前事务,假设当前没有事务,就以非事务方式运行
PROPAGATION_MANDATORY支持当前事务,假设当前没有事务,就抛出异常
PROPAGATION_REQUIRES_NEW新建事务,假设当前存在事务。把当前事务挂起
PROPAGATION_NOT_SUPPORTED以非事务方式运行操作。假设当前存在事务,就把当前事务挂起
PROPAGATION_NEVER以非事务方式运行,假设当前存在事务,则抛出异常
PROPAGATION_NESTED如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。

事务隔离级别和事务的传播行为的区别

事务传播行为(propagation behavior)指的就是当一个事务方法被另一个事务方法调用时,这个事务方法应该如何进行。

例如:methodA事务方法调用methodB事务方法时,methodB是继续在调用者methodA的事务中运行呢,还是为自己开启一个新事务运行,这就是由methodB的事务传播行为决定的。

事务的隔离性就是指,多个并发的事务同时访问一个数据库时,一个事务不应该被另一个事务所干扰,每个并发的事务之间要相互进行隔离。

总之,事务隔离级别作用于单个事务,而事务传播作用多个事务。事务隔离级别在配置,而事务传播一般通过AOP去配置。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值