SQL的事务隔离

本文详细介绍了SQL的四种事务隔离级别:读未提交、读提交、可重复读和串行化,以及它们在实际操作中的表现。重点讨论了可重复读隔离级别的MVCC机制和事务的启动方式,强调了长事务的影响,并提供了事务管理的建议。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SQL标准的事务隔离级别包括:读未提交(read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(serializable )。

  1. 读未提交是指,一个事务还没提交时,它做的变更就能被别的事务看到。
  2. 读提交是指,一个事务提交之后,它做的变更才会被其他事务看到。
  3. 可重复读是指,一个事务执行过程中看到的数据,总是跟这个事务在启动时看到的数据是一致的。当然在可重复读隔离级别下,未提交变更对其他事务也是不可见的。
  4. 串行化,顾名思义是对于同一行记录,会加写锁会加读锁。当出现读写锁冲突的时候,后访问的事务必须等前一个事务执行完成,才能继续执执行

下面看两个事务在不同的隔离级别中的表现。

事务A

事务B

启动事务,查询到值1

启动事务

 

查询到值1

 

把1改成2

查询到值V1

 

 

提交事务B

查询到值V2

 

提交事务A

 

查询到值B3

 

  1. 读未提交,则V1的值是2,B事务还没有提交A就已经看到了。
  2. 读提交,那么V1的值是1,因为b事务在提交后才能被A看到。V2=2,V3=2
  3. 可重复读,V1=1,V2=1,V3=2,之所以V2是1,因为事务A在执行期间看到的数据前后是一样的。可重复读隔离级别,事务T启动的时候会创建一个视图read-view,之后事务T执行期间,即使有其他事务修改了数据,事务T看到的仍然跟在启动时看到的一样。
  4. 串行化,A比B先执行,事务B在执行的时候,会被锁住,到事务A执行后,事务B才能执行,那么从A的角度看,V1=1,V2=1,V3=2。

数据库里面会创建一个视图,访问的时候以视图的逻辑结果为准。在“可重复读”隔离级别下,这个视图是在事务启动时创建的,整个事务存在期间都用这个视图。在“读提交”隔离级别下,这个视图是在每个SQL语句开始执行的时候创建的。这里需要注意的是,“读未提交”隔离级别下直接返回记录上的最新值,没有视图概念;而“串行化”隔离级别下直接用加锁的方式来避免并行访问。

事务隔离的实现

每条记录在更新的时候都会同时记录一条回滚操作。记录上的最新值,通过回滚操作,都可以得到前一个状态的值。

假设一个值从1被按顺序改成了2、3、4,在回滚日志里面就会有类似下面的记录:

 

不同时刻启动的事务会有不同的read-view,A,B,C中看到的值分别是1,2,4。同一条记录中国你可以存在多个版本,这个就是数据库的多版本并发控制(MVCC)。

       当系统里面没有比这个回滚日志更早的事务了,那么这个记录才会被删掉,所以我们一般不要使用长事务,否则储存空间里面会放着很多很老的回滚记录。

事务的启动方式

Mysql的启动方式有两种

  1. 显示启动事务,begin 或 start transaction。配套的提交语句是commit,回滚语句是rollback。执行到commit或者rollback的时候,事务会结束。
  2. set autocommit=0,将这个线程的自动提交关掉,每个SQL语句或者语句块所在的事务都需要显示"commit"才能提交事务,或者遇到rollback结束。

为了避免写代码错误导致长事务,建议使用set autocommit=1,通过显式语句的方式来启动事务。这种模式会在每条语句执行完毕后把它作出的修改立刻提交给数据库并使之永久化。事实上,这相当于把每一条语句都隐含地当做一个事务来执行。如果你想明确地执行事务,就显示得开始事务。

1、不管autocommit 是1还是0 

     START TRANSACTION 后,只有当commit数据才会生效,ROLLBACK后就会回滚。

2、当autocommit 为 0 时

    不管有没有START TRANSACTION。只有当commit数据才会生效,ROLLBACK后就会回滚。

3、如果autocommit 为1 ,并且没有START TRANSACTION 。调用ROLLBACK是没有用的

 

Ps. 如果在意每次开启一个事务都要调用begin,影响效率,那么在事务执行完后,执行commit work and chain,则是提交事务并自动启动下一个事务,这样也省去了再次执行begin语句的开销。

Ps2. 在information_schema库的innodb_trx这个表中查询长事务

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值