基础知识
事务简单来说,就是保证一组数据库操作要么全部成功,要么全部失败。MySQL中,在引擎层实现事务支持,其中InnoDB支持事务,MyISAM不支持事务。在InnoDB中提供四种隔离级别从低到高为:读未提交、读已提交、可重复读、串行。随着隔离级别的提高,事务执行的效率会降低。不同数据库的默认隔离级别并不相同,Oracle默认的隔离级别是读已提交。可以通过show variables like ' tx_isolation'
进行查看。
实现
在实现上,数据库里面会创建一个视图,访问的时候以视图的逻辑结果为准。在“可重复读”隔离级别下,这个视图是在事务启动时创建的,整个事务存在期间都用这个视图。在“读提交”隔离级别下,这个视图是在每个SQL语句开始执行的时候创建的。而 “读未提交”隔离级别下直接返回记录上的最新值,没有视图概念;“串行化”隔离级别下直接用加锁的方式来避免并行访问。
MySQL在创建视图的同时也会记录回滚操作,如下图所示,可以看出随着事务时间的增加,回滚段所占的空间会越来越大,所以,在对数据库进行操作时,要尽量避免长事务。
事务启动
- 显式启动事务,通过
begin
或start transaction
,提交语句是commit
,回滚语句是rollback
- 通过设置
set autocommit=0
,这个命令会将这个线程的自动提交关掉。意味着如果你只执行一个select
语句,这个事务就启动了,而且并不会自动提交。这个事务持续存在直到主动执行commit
或rollback
语句,或者断开连接,这时就有可能产生长事务,所以建议set autocommit=1
,设置自动提交。 - 此外对于频繁使用事务的业务来说,可以采用
commit work and chain
,提交之后自动开启下一事务。
长事务
select * from information_schema.innodb_trx where TIME_TO_SEC(timediff(now(),trx_started))>60
参考文献
MySQL实战45讲