简单说,事务就是保证一组数据库操作,要么全部成功,要么全部失败。MySQL的事务是在引擎层实现的,但并不是所有的引擎都支持事务,InnoDB支持事务,而原生的MyISAM就不支持。
事务的四大特性
Atomicity原子性
Consistency一致性
Isolation隔离性
Durability持久性
并发事务与隔离级别
数据库上有并发事务时,就会产生修改丢失、脏读、不可重复读、幻读的问题,为了解决并发事务问题,就有了‘隔离级别’的概念。SQL标准的隔离级别有:read uncommitted读未提交、read committed读已提交、repeatable read可重复读、serializable串行化,通过启动参数transaction-isolation设置隔离级别,查询SQL为:show variables like ‘transaction_isolation’。
RU读未提交:一个事务还没提交时,它做的变更就能被别的事务看到。
RC读已提交:一个事务提交后,它做的变更才能被别的事务看到。
RR可重复读:在满足RC的基础上,一个事务执行过程中看到的数据,总是跟这个事务在启动时看到的数据是一致的。
Serial串行化:对于同一行记录,写操作会加写锁,读操作会加读锁。当出现锁冲突时,后访问的事务必须等待前一个事务执行完成才能继续执行。
关于隔离级别和视图
数据库会创建一个视图,访问时以视图的逻辑结果为准。
RR级别下,视图是在事务启动时创建的,这个事务存在期间都用这个视图。
RC级别下,视图是在SQL开始执行时创建的。
RU级别下,没有视图概念,直接返回记录上的最新值。
Serial级别下,直接用加锁的方式来避免并行访问。
事务隔离级别的实现
每条记录在更新时,都会记录对应上一个版本的回滚操作。同一条记录在系统中可以存在多个版本,这就是数据库的多版本并发控制MVCC
事务的启动方式
1)通过begin或者start trancsation显示的启动事务,对应的提交语句是commit,回滚语句是rollback。
2)set autocommit = 0,关闭当前线程的主动提交,且事务开始时不需要主动执行begin。但这种方式会导致执行语句时事务自动开启,且直到主动执行commit或者rollback之前或者断开连接之前,事务会一直存在,也就意外产生了长事务问题。
长事务会导致事务中存在很老的视图,进而导致很老的视图的回滚记录也必须保存,这会导致占用大量的存储空间。所以尽量设置set autocommit = 1,避免自动开启事务。
可以在information_schema库的innodb_trx表,查询长事务。查询超过60s的事务:
select * from information_schema.innodb_trx where TIME_TO_SEC(timediff(now(),trx_started)) > 60
