当前位置:网站首页>事务的隔离级别与所带来的问题

事务的隔离级别与所带来的问题

2020-11-06 21:19:00 程序猿欧文

一、事务的基本要素(ACID)

  1、原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做,不可能停滞在中间环节。事务执行过程中出错,会回滚到事务开始前的状态,所有的操作就像没有发生一样。也就是说事务是一个不可分割的整体,就像化学中学过的原子,是物质构成的基本单位。

   2、一致性(Consistency):事务开始前和结束后,数据库的完整性约束没有被破坏 。比如A向B转账,不可能A扣了钱,B却没收到。

   3、隔离性(Isolation):同一时间,只允许一个事务请求同一数据,不同的事务之间彼此没有任何干扰。比如A正在从一张银行卡中取钱,在A取钱的过程结束前,B不能向这张卡转账。

   4、持久性(Durability):事务完成后,事务对数据库的所有更新将被保存到数据库,不能回滚。

二、SQL标准的事务隔离级别(mysql默认为可重复读,oracle默认为读已提交)

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

例子

事务一 事务二
启动事务A,查询A=10 启动事务B
查询A=10, 更新A=20
查询值a1
提交事务B
查询值a2
提交事务A
查询值a3
  • 若隔离级别是“读未提交”, 则a1的值就是20,虽然B没提交2但是结果已经A看到了

  • 若隔离级别是“读已提交”,则a1是10,a2的值是2。事务B的更新在提交后才能被A看到。所以, a3的值也是2。

  • 若隔离级别是“可重复读”,则a1、a2是10,a3是20。之所以a2还是10,遵循的就是这个要求:事务在执行期间看到的数据前后必须是一致的。

  • 若隔离级别是“串行化”,则在事务B执行“将A=10改成20”的时候,会被锁住。直到事务A提交后,事务B才可以继续执行。所以从A的角度看, a1、a2值是10,a3的值是20

三、如何设置和查看隔离级别

  • 读未提交:read uncommitted
  • 读已提交:read committed
  • 可重复读:repeatable read
  • 串行化:serializable

查看隔离级别

show variables like 'transaction_isolation';

设置innodb的事务级别方法是:set 作用域 transaction isolation level 事务隔离级别,例如~

SET [SESSION | GL.........

版权声明
本文为[程序猿欧文]所创,转载请带上原文链接,感谢
https://my.oschina.net/mikeowen/blog/4556922