数据库的事务与隔离级别详解
一、事务
简要介绍
事务在我认为就是在数据库中做某些事的时候,把这些事融合在一起,如果成功,那么都成功,反之都失败。
egg:开启事务,a给b转账,b收到转账,提交事务。这两件事由于在一个事务中,不会出现a转账了但是b没有收到的情况。
事务的四大特性
1.原子性
原子性很好理解,就是一个事务里边的多个操作,要么都成功,要么都失败。
2.一致性
事务必须使数据库从一个一致性状态变换到另外一个一致性状态。比如转账,转账前两个账户余额之和为100,转账之后也应该是100。
3.隔离性
隔离性其实就是比如两个事务的时候,a事务做的操作与b事务做的操作互不干扰。比如a事务做的事情是向这个银行卡转账,b事务也是往这张银行卡转账,在同一时间,这两个事务不能同时请求这一段数据。
4.持久性
持久性就是事务提交之后,在事务执行期间操作的数据会保留到磁盘上,及时数据库异常重启也不会丢失。
二、隔离级别
简要介绍
隔离级别的出现在我看来主要是为了应对并发操作,它其实是一种规则,就是同时出现了多种事务去读,写数据,处于不同的隔离级别下,会有不同的结果。隔离级别也是分为4种,下面写一些小例子来介绍各个隔离级别。1.未提交读
在这个规则下,a事务操作了数据,即使没有提交,b事务去查询这个数据也能查询到。
这里建了一个测试表来展示未提交读:
首先开启会话1,然后去操作数据(开启了数据但是不提交)。
然后开启会话2,去查询刚才修改的数据,发现能查询到数据已经变成了100。
但是此时表里边的数据还是会话1修改之前的数据(事务还没有提交,并没有持久化到磁盘上)。
2.已提交读
在这个规则下,a事务去修改了数据,只有提交了(也可以理解为持久化到磁盘上b才可以看到)
将会话1设置为已提交读然后去操作数据
会话2去查询,没有发现数据被修改。
将会话1的事务提交。
会话2发现数据已经被修改,同时数据库中的数据已经持久化。
3.可重复读
在这种规则下,无论事务a怎么操作数据,事务b在事务提交之前查询的值保持不变。 首先会话1把数量改成99,然后提交了。
然后会话2开启事务去查询,数量为99。
然后会话将数量修改为1。
然后用没有提交事务的会话2去查询,发现数量还是99,但是此时数据库中持久化的值已经变成了1。
提交会话2再开启事务查询,发现数量才变成1。
4.串行化的
在这种规则下,同一段数据,在事务a进行查询的时候,事务b是不能进行修改的,会被锁住(这个锁的机制暂时不讲,后边会专门出一章),可以理解为是一种限制,a查询的数据别人不能动。
首先开启会话1去查询一张表的数据,只开启事务但是不提交。
然后会话2去修改数据,发现操作一直没有返回。
然后把会话1提交之后,会话2的修改才执行完。
对于隔离级别的总结
1.未提交读,事务未提交也可以看到被修改的数据,会出现脏读现象,a修改了数据但是没持久化到数据库,b查看的不是数据库中持久化的数据,而是a修改的数据。
2.已提交读是为了解决脏读这种现象的一种隔离级别,只有持久化到数据库的数据才能查询到,但是查询时还会出现一种情况是,在a事务查询的过程中,b事务对这个数据进行了修改,那么在a事务没有提交之前,同样的查这个数据,两次查询是不一样的值,这种情况一般称之为不可重复读。
3.可重复读是为了解决不可重复读这种现象的一种隔离级别,就是a事务在查询这一段数据的时候,无论b事务怎么修改,开启事务的时候数据库的值,多次查询的值是一样的,但是查询的时候还会出现一种情况,就是明明查询的是这个值,但是看着数据库里边却是另一个值,这种现象就是幻读。
4.串行化这种隔离级别可以解决幻读的情况,但是效率很低了就,相当于在有事务查询的情况下,这个数据是不可以修改的,查询完之后,才能修改数据。