MySQL事务隔离
-
事务的特征,原子性,一致性,持久性,隔离性;
-
原子性:事务提交之前要么成功,要么失败;
-
一致性:比如转账我给其他用户转换,减少和增加余额前后是一致的;
-
持久性:数据的提交之后,保存到数据库就是永久的;
-
隔离性:并发的事务提交是相互隔离的,互不干扰;
-
多个事务执行的时候出现的问题:脏读,不可重复读,幻读,解决此些问题,有了事务隔离;
事务类型:
- 读未提交:一个事务还未提交时,它做的变更就能别的事务看到。
- 读提交:一个事务提交之后,它做的变更才会被其他事务看到。
- 可重复读;一个事务执行过程看到的数据,总是跟这个事务在启动时看到的数据是一致的。当然执可重复读隔离级别下,未提交变更对其他事务也是不能见的;
- 串行化:同一行记录,写会加写锁,读会加读锁,当出现读写锁冲突的时候,后访问的事务必须等前一个事务执行完成,才能继续执行;
如图:
读未提交:v1的值是2,事务B未提交,但是结果已经被A看到了,因此v2,v3,也都是2;
读提交:和上面相反,所有之后要事务之后,才能被其他看到;
可重复读:则v1,v2是1,v3是2,之所以v2还是1,遵循的是前后看到的数据是一致的;
串行化:事务b执行将1改成2,会被锁住;直到A提交后,B事务才可以继续执行;
如何查询事务级别?
show variables like 'transaction_isolation';
事务隔离的实现
- 假设一个值从 1 被按顺序改成了 2、3、4,在回滚日志里面就会有类似下面的记录;
当前值是 4,但是在查询这条记录的时候,不同时刻启动的事务会有不同的 read-view。如图中看到的,在视图 A、B、C 里面,这一个记录的值分别是 1、2、4,同一条记录在系统中可以存在多个版本,就是数据库的多版本并发控制(MVCC)。对于 read-view A,要得到 1,就必须将当前值依次执行图中所有的回滚操作得到,同时你会发现,即使现在有另外一个事务正在将 4 改成 5,这个事务跟 read-view A、B、C 对应的事务是不会冲突的。
事务启动方式
- 显式启动事务语句, begin 或 start transaction。配套的提交语句是 commit,回滚语句是 rollback。
- set autocommit=0,这个命令会将这个线程的自动提交关掉。意味着如果你只执行一个 select 语句,这个事务就启动了,而且并不会自动提交
查找事务长事务
- select * from information_schema.innodb_trx where TIME_TO_SEC(timediff(now(),trx_started))>60