MYSQL数据库事务隔离(ACID)的四个级别

1、数据库支持事务,必须具备以下四个特性:
  1. 原子性(Atomicity):原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚。
  2. 一致性(Consistency):一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态,也就是说一个事务执行前和执行后都必须处于一致性状态。举个例子:拿转账来说,假设用户A和用户B两者的钱加起来一共是5000,那么不管A和B之间如何转账,转几次账,事务结束后两个用户的钱加起来应该还是5000,这就是事务的一致性。
  3. 隔离性(IsoIation):隔离性是当多个用户并发访问数据库时,比如操作同一张表时,数据库为每一个用户开启的事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离。
  4. 持久性(Durability):持久性是指一个事务一旦被提交了,那么对数据库中数据的改变就是永久性的,即使是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。
2、不考虑事务隔离可能遇到的问题
  1. 脏读:脏读是指在一个事务处理过程中读取了另一个未提交的事务中的数据。
  2. 不可重复读:不可重复读是指在对于数据库中的某个数据,一个事务范围内多次查询却返回了不同的数据值,这是由于在查询间隔期,被另一个事务修改并提交了。
  3. 虚读(幻读):幻读是事务非独立执行时发生的一种现象。例如事务T1对一个表中所有的行的某个数据项做了从“1”修改为“2”的操作,这时事务T2又对这个表中插入了一行数据项,而这个数据项的数值还是为“1”并且提交给数据库。而操作事务T1的用户如果再查看刚刚修改的数据,会发现还有一行没有修改,其实这行是从事务T2中添加的,就好像产生幻觉一样,这就发生了幻读。

幻读和不可重复读都是读取了另一条已经提交的事务(这点就脏读不同),所不同的是不可重复读查询的都是同一个数据项,而幻读针对的是一批数据整体(比如数据的个数)。

3、MySQL数据库的四种隔离级别

MySQL的事务隔离级别,是为了解决在分布式并发场景中并发读写的一致性问题。若是在单线程的程序中,是不需要隔离级别的概念的,因为天生就是单线程的执行顺序,并不存在并发读写一致性问题。

MYSQL数据库事务隔离(ACID)的四个级别分别是:

  1. 读未提交(Read Uncommitted):最低级别,任何情况都无法保证。
  2. 读已提交(Read Committed):可避免脏读的发生。
  3. 可重复读(Repeatable Read):可避免脏读和不可重复读的发生。
  4. 串行化(Serializable):可避免脏读、不可重复读、幻读的发生。

  以上四种隔离级别最高是Serializable级别,最低默认的为Read Uncommitted级别,当然级别越高,执行效率就越低。像Serializable这样的级别,就是以锁表的方式(类似于Java多线程的锁)使得其它线程只能在锁表外等待,所以平时选用何种隔离级别应该根据实际情况。在MySQL数据库中默认的隔离级别为Repeatable read(可重复读)

  在MySQL数据库中,支持上面四种隔离级别,默认的为Repeatable read(可重复读);而在Oracle数据库中,只支持Serializable(串行化)级别和Read committed(读已提交)这两种级别,其中默认的为Read committed级别。

在MySQL数据库中当前事务的隔离级别:

select @@tx_isolation;

在MySQL数据库中设置事务的隔离级别:

set [glogal | session] transaction isolation level 隔离级别英文名称;

注:设置数据库的隔离级别一定要在开启事务前!

4、MySQL可重复读的好处

这个一般在面试过程中,只要问到数据库的隔离级别,一般就会问到MySQL设置默认隔离级别为Repeatable Read(可重复读)的好处。先来了解一下可重复读隔离视图原理。

MySQL实现可重复读隔离级别是采用**MVCC(多版本并发控制)**来实现,事务内在正式启动时会产生一个快照视图,在此视图的基础上进行读取操作。其它事务发生增删改查,只要本事务生成快照视图后,都不会发生影响。

什么时候正式产生快照?快照是在begin语句后第一条执行语句时开始产生快照视图。若想手动触发产生快照视图,可以采用以下的语句进行快照视图的手动触发

start transaction with consistent snapshot;

需要特别注意的是,一般mysql会设置autocommit=1,这样执行完update语句后会自动commit,不需要显示提交。

为什么要实现可重复读呢?主要还是为了在并发环境下得到一个稳定的结果,比如在财务对账中,我要读取账目的情况,这是一个查询操作,而我恰恰在查询的过程中,有另外的事务对账目表进行修改操作,但是我想查询的是我需要的那个时刻的结果,所以其他操作不能影响我的查询操作,即实现了可重复读,可重复读相对于序列化性能上能更灵活些,因为序列化可以理解成一个单线程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值