五、mysql中事务的隔离级别

目录

5.1. 事务的隔离性

5.2. 事务隔离的实现

5.3. mysql事务的启动方式

5.4. 如何查询长事务?

5.5. 如何修改事务的隔离级别为读已提交?

5.6. 事物到底是隔离的还是不隔离的?

在mysql里,有两个“视图”的概念:

“快照”在MVCC里是怎么工作的?

事物的可重复读的能力是怎么实现的?


5.1. 事务的隔离性

读未提交是指,一个事务还没提交时,它做的变更就能被别的事务看到。

读提交是指,一个事务提交之后,它做的变更才会被其他事务看到。

可重复读是指,一个事务执行过程中看到的数据,总是跟这个事务在启动时看到的数据是一致的。当然在可重复读隔离级别下,未提交变更对其他事务也是不可见的。

串行化,顾名思义是对于同一行记录,“写”会加“写锁”,“读”会加“读锁”。当出现读写锁冲突的时候,后访问的事务必须等前一个事务执行完成,才能继续执行。

提到事物,会想到ACID(Atomicity、Consistency、Isolation、Durability),即原子性、一致性、隔离性、持久性,这里简单说说其中的I,也就是“隔离性”。

当数据库上有多个事物同时执行的时候,就可能出现脏读、不可重复读、幻读的问题,为了解决这些问题,就有了“隔离级别”的概念。

在谈隔离级别之前,首先要知道,隔离级别越严实,效率就会越低。因此需要在两者之间寻找一个平衡点。SQL标准的事物隔离级别包括:读未提交、读提交、可重复读和串行化。

 

 

5.2. 事务隔离的实现

    同一条记录,再系统中 可以存在多个版本,就是事务的多版本并发控制(MVCC),不同时刻启动的事务会有不同的read-view, 对于 read-view A,要得到 1,就必须将当前值依次执行图中所有的回滚操作得到.

那么回滚日志什么时候删除尼? 就是当系统里没有比这个回滚日志更早的 read-view 的时候;所以尽量不要使用长事物。(长事务意味着系统里面会存在很老的事务视图。由于这些事务随时可能访问数据库里面的任何数据,所以这个事务提交之前,数据库里面它可能用到的回滚记录都必须保留,这就会导致大量占用存储空间)

 

5.3. mysql事务的启动方式

显式启动事务语句, begin 或 start transaction。

配套的提交语句是 commit,回滚语句是 rollback;

set autocommit=0,这个命令会将这个线程的自动提交关掉。意味着如果你只执行一个 select 语句,这个事务就启动了,而且并不会自动提交。这个事务持续存在直到你主动执行 commit 或 rollback 语句,或者断开连接。

对于一个需要频繁使用事务的业务,第二种方式每个事务在开始时都不需要主动执行一次 “begin”,减少了语句的交互次数。如果你也有这个顾虑,我建议你使用 commit work and chain 语法;在 autocommit 为 1 的情况下,用 begin 显式启动的事务,如果执行 commit 则提交事务。如果执行 commit work and chain,则是提交事务并自动启动下一个事务,这样也省去了再次执行 begin 语句的开销。同时带来的好处是从程序开发的角度明确地知道每个语句是否处于事务中

 

5.4. 如何查询长事务?

在 information_schema 库的 innodb_trx 这个表中查询长事务,比如下面这个语句,用于查找持续时间超过 60s 的事务

select * from information_schema.innodb_trx where TIME_TO_SEC(timediff(now(),trx_started))>60

 

5.5. 如何修改事务的隔离级别为读已提交?

将启动参数 transaction-isolation 的值设置成 READ-COMMITTED。你可以用 show variables 来查看当前的值。

mysql> show variables like 'transaction_isolation';

+-----------------------+----------------+

| Variable_name | Value |

+-----------------------+----------------+

| transaction_isolation | READ-COMMITTED |

+-----------------------+---------------+

5.6. 事物到底是隔离的还是不隔离的?

在mysql里,有两个“视图”的概念:

1、view:它是一个用查询语句定义的虚拟表,在调用的时候执行查询语句并生成结果。创建视图的语法是create view...,而它的查询方法与表一样。

2、InnoDB在实现MVCC时用到的一致性读视图,即consistent read view,用于支持RC(read committed,读提交)和RR(Repeatable Read,可重复读)隔离级别的实现。

它没有物理结构,作用是事物执行期间用来定义“我能看到什么数据”。


“快照”在MVCC里是怎么工作的?

一个数据版本,对于一个事物视图来说,除了自己的更新总是可见以外,有三种情况:

1、版本未提交,不可见;

2、版本已提交,但是是在视图创建后提交的,不可见;

3、版本已提交,而且是在视图创建前提交的,可见。

规则:更新数据都是先读后写的,而这个读,只能读当前的值,称为“当前读”。

mysql> select k from t where id=1 lock in share mode;

mysql> select k from t where id=1 for update;


事物的可重复读的能力是怎么实现的?

可重复读的核心就是一致性读(consistent read);而事物更新数据的时候,只能用当前读。如果当前的记录的行锁被其他事物占用的话,就需要进入锁等待。

读提交的逻辑和可重复读类似,他们最主要的区别是:

1、在可重复读隔离级别下,只需要在事物开始的时候创建一致性视图,之后事物里的其他查询都共用这个一致性视图;

2、在读提交隔离级别下,每一个语句执行前都会重新算出一个新的视图。


  1. InnoDB的行数据有多个版本,每个数据版本有自己的row trx_id,每个事物或者语句都有自己的一致性视图。普通查询语句是一致性读,一致性读会根据row trx_id和一致性视图确定数据版本的可见性。
  2. 对于可重复读,查询只承认在事物启动前就已经提交完成的数据;
  3. 对于读提交,查询只承认在语句启动前就已经提交完成的数据。
  4. 而当前都,总是读取已经提交完成的最新版本。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

发哥1997

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值