本文共 2156 字,大约阅读时间需要 7 分钟。
事务的ACID特性:原子性、一致性、隔离性、持久性。这部分不多说了,任何一本讲数据库理论的书籍里边都会有讲。MySQL InnoDB通过锁来实现事务的一致性和隔离性,共实现了四种事务隔离级别:
· READ UNCOMMITTED 读取未提交
某个session中的事务可以看到其他session的事务中尚未提交的更改,而该更改可能回滚,即会出现”脏读“;1:这种隔离级别几乎不被使用,在selelct将会看到各种奇怪的数据现象,当然包括其它事务还未提交的数据。2:强烈不推荐,不能保证数据的一致性。
· READ COMMITTED 读取提交
某个session中的事务只可以看到其他session的事务中已经提交的更改,不会出现”脏读“,但一个事务对同一对象的两次查询结果可能出现不一致,即会出现“不可重复读”;1:每一个select都会使用各自的数据状态的快照。2:如果当前的数据状态已更新到最新,但是当当个select的时候仍然会产生不一致的数据状态。3:更少的间隙锁意味着更少的死锁。4:唯一key的检查在第二索引和其它外键检查的时候也会产生间隙所。(gap必须被锁定以防止在parent row被删除后仍在child row中插入相关数据)。5:这种隔离级别也是使用的非常普遍的隔离级别尤其是在5.1以后的版本中。6:征对在5.0更早的版本中,可以通过innodb_locks_unsafe_for_binlog移除gap locking。(In V5.1, most gap-locking is removed w/ this level, but you MUST use row-based logging/replication。)
· REPEATABLE READ 可重读
某个session中的事务不能查询到其他session的事务中未提交和已经提交的更改,不会出现”不可重复读”,但期间,其他事务却可能对数据进行更改并提交,而这些更改对前一个事务中的INSERT/UPDATE/DELETE等语句是可见的,因此可能出现”更新丢失“,另外,虽然SELECT不到,但对其进行更改操作时却真实的存在,就好像幻象一样,且更改过后可以被同一事物中的SELECT看到,也即”幻像读“(其实”不可重复读”也可理解为”幻像读“,因为同一事务中前后两次读取到的结果不一样,看个人怎么理解了,这些叫法只是一个名字而已);1:所有的select在第一次一致读以后在事务中都会使用一样的数据状态快照。2:update,delete都会使用间隙锁来保证数据的安全。防止phantom。3:这是采用最广的事务隔离级别,也是mysql默认的事务隔离级别。
· SERIALIZABLE 可串行化
使事务串行化执行,解决上述问题。1:这种隔离级别对数据的要求最为严格,自然也是性能最差的一种隔离级别。在所有的select语句中都是默认加了一个lock in share mode的锁,2:在这种隔离级别中没有一致读的,所有的select都将返回最近的数据状态。3:由于这种隔离级别的对数据高度一致的严格,所以会产生很多的锁,自然也会导致很多的死锁,对性能的影响不言而喻。
若 MySQL 变量 autocommit 设置为 1 ,也即开启了自动提交特性,则事务隐式的开启/关闭,每条SQL自成一个事务,执行后事务自动提交 。此时,也可通过 START TRANSACTION/BEGIN 显式的开启事务,而通过COMMIT/ROLLBACK显式结束事务;若变量 autocommit 设置为 0,也即关闭了自动提交特性,则连接的session会始终保持开启一个事物,可通过COMMIT/ROLLBACK 显式的结束事务并开启新的事务。锁在事务内的每条SQL语句中逐个获取而在事务结束后被全部释放。
查看全局和session的事务隔离级别
SELECT @@global.tx_isolation, @@session.tx_isolation;
设置全局和session级别的事物隔离级别。
需注意的是若指定了 GLOBAL 关键字则会对所有后续的 session 生效而对当前session无效。若指定了SESSION关键字则会对当前 session 中的后续的事务生效而对当前事务无效。若没有指定任何关键字则仅对当前session中接下来的一个事务生效。
SET GLOBAL/SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;SET GLOBA/SESSIONL TX_ISOLATION='REPEATABLE-READ';
CREATE TABLE t1 (i INT, PRIMARY KEY (i)) ENGINE = InnoDB;
开启两个session,SESSION A和SESSIONB。InnoDB默认事务隔离级别为 REPEATABLE READ。我们先从最低的隔离级别开始READ UNCOMMITTED测试。
转载地址:http://afoii.baihongyu.com/