MySQL笔记-事务隔离级别
事务四大特性
原子性
一致性
隔离性
持久性
多个事务同时执行的时候可能出现的问题
脏读
不可重复读
幻读
为了解决上述问题,引入事务隔离级别
读未提交:别人改数据的事务尚未提交,我在我的事务中也能读到
实现方法:直接返回记录上的最新值。
读已提交:别人改数据的事务已经提交,我在我的事务中才能读到
实现方法:数据库创建一个视图,访问的时候以视图的逻辑结果为准,每个sql执行时创建新的视图。
可重复读:别人改数据的事务已经提交,我在我的事务中也不去读
实现方法:数据库创建一个视图,访问的时候以视图的逻辑结果为准,每个事务开始时创建视图,整个事务期间用同一个视图。
串行:我的事务尚未提交,别人就别想改数据
这四种隔离级别,并行性能依次降低,安全性依次提高。
事务隔离的实现原理:
在 MySQL 中,实际上每条记录在更新的时候都会同时记录一条回滚操作。记录上的最新值,通过回滚操作,都可以得到前一个状态的值。以可重复读级别为例,在事务开始时创建的视图,因为回滚操作记录的存在,事务结束前任意时刻,都可以获取这个视图创建之初时某个字段的值。
小知识:
Oracle数据库的默认隔离级别其实就是“读提交”,因此对于一些从Oracle迁移到MySQL的应用,为了保证数据库隔离级别一致,一定要记得将MySQL的隔离级别 设置为“读提交”。
mysql查询数据库的隔离级别:
5.6版本&以前:SHOW VARIABLES like 'tx_isolation';
5.7版本&以后:SHOW VARIABLES like 'transaction-isolation';
不建议使用长事务的原因:
长事务意味着系统里面会存在很老的事务视图。由于这些事务随时可能访问数据库里面的
任何数据,所以这个事务提交之前,数据库里面它可能用到的回滚记录都必须保留,这就
会导致大量占用存储空间。
查看长事务:
SELECT * FROM information_schema.INNODB_TRX WHERE TIME_TO_SEC(TIMEDIFF(NOW(),trx_started));