《MySQL实战45讲》学习笔记——事务隔离

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Q52077987/article/details/84871082

SQL标准事务隔离的级别包括:

  • 读未提交,read uncommitted,一个事务还没有提交,它做的变更就能被别的事务看到。
  • 读提交,read commited,一个事务提交之后,它做的变更才会被其他事务看到。
  • 可重复读,repeatable read,一个事务执行的过程中看到的数据,总是跟这个事务在启动的时候看到的数据是一致的。
  • 串行化,对于同一行记录,加读写锁。如果事务读写冲突,必须串行。

”读未提交“直接使用当前数据执行事务;”串行化“通过加锁的方式使用当前数据执行事务,两者不同的是后者因为加锁,所以在事务执行期间不可能产生数据冲突。

对于”可重复读“隔离级别,会在事务启动的时候创建一个视图,事务使用视图数据;对于”读提交“隔离级别,这个视图是在每个SQL语句开始执行的时候创建的。

MVCC机制

每一行数据都有一个版本号,这个版本号就是写入这行数据的事务ID,事务是唯一的,自增的。MVCC保留了未提交数据的历史版本。这就是undolog。

可重复读创建的视图是虚拟的,就是事务的ID,当事务读取一行数据的时候,如果当前的数据版本号高于事务ID,就向上追溯,直到事务ID那个版本。(忽略事务开始前未提交事务的版本,这个和写入有关,后边还会解释)

长事务可能会造成较大的回滚日志。

在MySQL 5.5以及以前的版本,回滚日志跟数据字典一起放在ibdata文件里,即使长事务最终提交,回滚段被清理,文件也不会变小

如何避免长事务对业务影响?(原文摘抄)

从应用开发端来看:

  • 确认是否开启了autocommit,这个第一步通过SQL语句show variables like 'autocommit'查看数据库是否启用,但是这样做是不够的,因为有些开发框架也会设置这个值,所以最终还是要看MySQL的general_log来确认。最终确保开启了autocommit。
  • 确认是否有不必要的只读事务,主要是有些框架会做,把这些只读的事务去掉
  • 业务连接数据库的时候,根据业务本身预估,通过SET MAX_EXECUTION_TIME命令,来控制每个语句执行的最长时间,避免单个语句意外执行太长时间。

从数据库角度来看:

  • 监控 information_schema.Innodb_trx表,设置长事务阈值,超过了就报警或者Kill
  • Percona的pt-kill这个工具不错,推荐使用
  • 在业务功能测试阶段输出所有的general _log,分析日志提前发现问题
  • 如果使用的是MySQL5.6或者更新的版本,把innodb_undo_tablespaces设置成2(或者更大值)如果真的出现大事务导致回滚段过大,这样设置后清理起来方便。

事务的写入

写不一样,写如果不在当前版本写,就没有意义。因为后来的查询只查询当前版本,并且undolog很快会被删掉。所以写入操作是在当前版本写。

写入后的查询呢?版本号一定是跟着写操作改变的,事务在当前版本写入数据后,当前版本就成为了历史版本,而改后当前的版本就是当前事务的ID,所以当前事务查询不需要回溯,取到的就是修改后的值。通过这一步可以得出一个重要结论,数据行的历史版本号不一定是按照从小到大的顺序排列的。

两个事物同时写,靠行锁保证数据一致性的。行锁为什么要等到事务提交才释放?因为如果提前释放,可能就会被别的事务修改,当前行的版本号又会改变,如果需要再次修改,当前读的数据就不是自己设定的数据,这个事务的逻辑就不可控了。事务提交才释放,能保证整个事务内部逻辑一致性。

上边提到的忽略事务开始前未提交事务ID的问题。
如果数据行的历史版本号不是按照从小到大排列的,那么一个事务在查询的时候是如何知道使用哪个版本的数据呢?如果这个事务在查询之前修改过,那么使用的就是自己ID的版本的数据;如果没有修改过,就比较复杂了,因为即使数据的版本号比自己的事务ID小,也可能是当前事务启动后提交的。解决的办法是在事务启动的时候记录所有未提交的事务ID,在查询搜索版本的时候忽略他们。

TIPS:
事务中使用当前读:
mysql> select k from t where id=1 lock in share mode;
mysql> select k from t where id=1 for update;

立即开始一个事务:
begin /start transaction并不是一个事务的起点,在执行第一个操作的时候事务才真正启动,可以用start transaction with consistent snapshot

猜你喜欢

转载自blog.csdn.net/Q52077987/article/details/84871082
今日推荐