【spring事务前置知识】事务的基本特性 + 隔离级别


1 最近打算

最近在研究spring事务的源码,因为spring事务的核心流程其实和spring-aop的核心流程很像,所以本想趁热打铁直接写几篇文章总结一下spring事务的核心流程的。但是今天下午突然想到之前在学校里为了考试,自己背诵事务的基本特性、事务隔离级别的时光。。。想到当时为了能拿满分,硬是非要按照当时的讲义一字不错的背下来的执着。。。想到当时在学校里其实学了那么多东西,但是却都留在了当时。。。

于是我决定这次从事务的基本特性+事务的隔离级别开始,先好好的整理一下事务的基础知识,就算这次整理完,之后随着时间的推移这部分内容又会在我的记忆里慢慢逝去,但我相信只要再次来到这里,我肯定会很快地就可将这部分内容重新拾起。


2 事务的基本特性

事务存在的意义是为了保证即使在并发情况下也能正确的执行crud操作。怎样才算是正确的呢?这时提出了事务需要保证的四个特性即ACID:

  • A:原子性(atomicity)
    指的是事务中各项操作,要么全部成功,要么全部失败;
  • C :一致性(consistency)
    事务的执行使数据从一个状态转换为另一个状态,但是对于整个数据的完整性保持稳定。 — 记得很清楚当时有个同学说就是“能量守恒定律”,即我给你转了100块钱,我这里肯定少了100块,你那里肯定也只能多了100块。
  • I :隔离性(isolation)
    并发执行的事务彼此无法看到对方的中间状态;
  • D:持久性(durability)
    事务完成后所做的改动都会被持久化,即使发生灾难性的故障 —> 通过日志和同步备份可以在故障发生后重建数据。

事务的ACID特性是由关系数据库系统(DBMS)来实现的,DBMS采用日志来保证事务的原子性、一致性和持久性。 日志记录了事务对数据库所作的更新,如果某个事务在执行过程中发生错误,就可以根据日志撤销事务对数据库已做的更新,使得数据库回滚到执行事务前的初始状态。

对于事务的隔离性,DBMS是采用锁机制来实现的。 即当多个事务同时更新数据库中相同的数据时,只允许持有锁的事务能更新该数据,其他事务必须等待,直到前一个事务释放了锁,其他事务才有机会更新该数据。

在高并发的情况下,要完全保证其ACID特性是非常困难的,除非把所有的事务串行化执行,但带来的负面影响将是性能大打折扣。所以数据库中针对隔离性设计了四种隔离级别,供用户基于业务进行选择。


3 事务的隔离级别

事务的隔离级别主要有四个,即读未提交(Read Uncommitted)、读已提交(Read Committed)、可重复度(Repeatable Read)和串行化(Serializable)。它们可能出现的问题如下:
在这里插入图片描述
接下来解释一下脏读、不可重复度和幻读。

  • 脏读
    A事务读到了B事务未提交的数据,就是所谓的脏读。

  • 不可重复读
    在同一个事务内的两个时间点读取同一个数据,读取到了不同的值,即发生了不可重复度。
    更具体点的解释:A事务在时间点t1读到了某数据的数值为data1, 在A事务未结束时,事务B更新了该数据的数值,假设更新为data2,并在时间点t2提交了事务, 事务A在时间点t2之后再次读该数据,发现此时数据变为data2了,而不是之前的data1了。

  • 幻读
    由于mysql的默认隔离级别为可重复读,因此不会出现脏读和不可重复读,因此如果当数据库使用的是mysql的话,最容易出现的就是幻读。那什么是幻读呢?用如下两个栗子来说明。

    • 栗子①: A事务在时间点t1读到了数据D的数值为1000, 在A事务未结束时,事务B更新了该数据的数值,假设更新为1100,并在时间点t2提交了事务,事务A在时间点t2之后再次读该数据 —> 这时候该数据肯定仍为1000(如果为1100就为不可重复读了),但是事务A在时间点t2之后,对该数据做了一次D = D+100的操作,之后再去查询数据D时,发现结果却为1200 —>按理说事务A刚刚在时间点t2之后还查到数据D的值为1000,仅仅对数据D做了一次D = D+100的操作,结果却成了1200,好像事务A刚才在时间点t2之后看错了,出现了幻觉一样 —> 即出现了幻读。
    • 栗子②: 事务A要对当前的所有员工都发1000块钱的奖金,于是先查了一下所有的员工数据,发现工资表里有小王、小李、小赵三个人,于是打算做一次更新工资的操作update t_salary set salary = salary + 1000;,但是在事务A进行更新操作之前,事务B在数据库里插入里一条数据小马,并提交了事务。之后事务A开始进行更新操作,按说它刚刚看到只有三人,但是更新操作却显示更新了4条记录,而且查表一看果然有四条数据,可是刚刚明明看到的是三条数据啊,怎么又成四条了,好像出现了幻觉一样 —> 即出现了幻读。

    通过上面两个栗子,可以总结一下出现幻读的场景:A事务和B事务同时操作一份数据D,假设B事务对数据D进行了修改并进行了提交,事务A再对数据D进行操作,在操作之前事务A看到的数据D仍然是B事务修改之前的数据,但当事务A对数据D进行修改时,却是对事务B修改后的数据进行修改。

发布了189 篇原创文章 · 获赞 187 · 访问量 39万+

猜你喜欢

转载自blog.csdn.net/nrsc272420199/article/details/103518732