只读事务是什么?
只读事务是指从这一点设置的时间点开始,到这个事务结束的过程中,其他事务所提交的数据,该事务看不见。
只读事务的作用
在 MySQL 上的只读事务,可以用来优化 InnoDB 表上查询事务创建的效率,并可以提供非锁定查询的性能。
InnoDB 引擎通过以下两种方式来检测一个事务是否是只读事务:
- 通过 START TRANSACTION READ ONLY 语句来检测。在读事务中如果有对数据库的修改操作(InnoDB,MyISAM 或其他类型的数据表),那么将会产生一个错误,并且事务会继续以只读事务进行。但是在只读事务中,你可以对
session
级别的临时表进行操作,又或者执行一个锁定查询。这是因为这些修改和加锁操作对其他事务是不可见的。 - 打开
autocommit
设置,此时事务确保只有一个 SQL 语句被执行,并且事务中的语句是一个非锁定查询的语句。非锁定查询的语句指的是不使用FOR UPDATE
或LOCK IN SHARED MODE
限制的查询语句。这样,针对报表生成这类查询比较集中的应用,你可以将一些查询语句组合起来放在一个START TRANSACTION READ ONLY
和COMMIT
语句中间,或者在执行查询语句前打开autocommit
设置,又或者避免在事务中的多个语句中包含导致数据变化的语句。
只读事务的优点是什么?
由于只读事务不存在数据的修改,因此数据库将会为只读事务提供一些优化手段。例如:
- Oracle 对于只读事务,不启用回滚段,不记录回滚 log。
- MySQL 可以避免为已知的只读事务设置事务 ID(
TRX_ID
字段)所带来的开销。事务 ID 仅用于可能执行写操作或锁读(如SELECT …… FOR UPDATE
)的事务。消除不必要的事务 ID 可以减少每次查询或数据更改语句构造读视图时所查询的内部数据结构大小。