14.5.2.1 Transaction Isolation Levels

  • Transaction isolation is one of the foundations of database processing. Isolation is the I in the acronym ACID; the isolation level is the setting that fine-tunes the balance between performance and reliability, consistency, and reproducibility of results when multiple transactions are making changes and performing queries at the same time.
  • 事务隔离是数据库处理的基础之一,Isolation是ACID中I的缩写,当多个事务同时进行更改和执行查询时,隔离级别是微调性能和可靠性、一致性和结果再现性之间的平衡的设置
  • InnoDB offers all four transaction isolation levels described by the SQL:1992 standard: READ UNCOMMITTED, READ COMMITTED, REPEATABLE READ, and SERIALIZABLE. The default isolation level for InnoDB is REPEATABLE READ.
  • InnoDB 提供了由 SQL:1992 标准描述的所有四个事务隔离级别,分别是 READ UNCOMMITTED, READ COMMITTED, REPEATABLE READ, and SERIALIZABLE,innob的默认隔离级别是REPEATABLE READ.
  • A user can change the isolation level for a single session or for all subsequent connections with the SET TRANSACTION statement. To set the server's default isolation level for all connections, use the --transaction-isolation option on the command line or in an option file. For detailed information about isolation levels and level-setting syntax, see Section 13.3.6, “SET TRANSACTION Syntax”.
  • 用户可以使用SET TRANSACTION语句更改单个会话或所有后续连接的隔离级别。如果想为所有连接设置服务默认隔离级别,那么在命令行使用 --transaction-isolation选项或者修改对应的配置文件,关于隔离级别和级别设置语法的详细信息,请看 Section 13.3.6, “SET TRANSACTION Syntax”.
  • InnoDB supports each of the transaction isolation levels described here using different locking strategies. You can enforce a high degree of consistency with the default REPEATABLE READ level, for operations on crucial data where ACID compliance is important. Or you can relax the consistency rules with READ COMMITTED or even READ UNCOMMITTED, in situations such as bulk reporting where precise consistency and repeatable results are less important than minimizing the amount of overhead for locking. SERIALIZABLE enforces even stricter rules than REPEATABLE READ, and is used mainly in specialized situations, such as with XA transactions and for troubleshooting issues with concurrency and deadlocks.
  • InnoDB使用不同的锁定策略支持此处描述的每个事务隔离级别,您可以使用默认的 REPEATABLE READ级别强制执行高度一致性,以便对ACID合规性很重要的关键数据进行操作。。或者您可以使用READ COMMITTED 甚至READ UNCOMMITTED,来放松一致性规则。在诸如批量报告这样的情况下,精确的一致性和可重复的结果比最小化锁定的开销量要小得多 SERIALIZABLE执行比REPEATABLE READ,更严的规则,主要用于特殊场合。比如XA事务,以及解决并发和死锁问题。
  • The following list describes how MySQL supports the different transaction levels. The list goes from the most commonly used level to the least used.
  • 下面的列表描述了MySQL如何支持不同的事务级别,列表显示从最常用的级别到最不常用的级别

    #REPEATABLE READ 可重复读

    • This is the default isolation level for InnoDB. Consistent reads within the same transaction read the snapshot established by the first read. This means that if you issue several plain (nonlocking) SELECT statements within the same transaction, these SELECT statements are consistent also with respect to each other. See Section 14.5.2.3, “Consistent Nonlocking Reads”.
    • 这是innodb默认的隔离级别,同一事务中的Consistent reads 读取由第一个读取建立的快照,意味着如果你在同一个事务中发送多次一样(没有锁的)的select语句,这些SELECT语句在相互之间也是一致的。更多信息请看Section 14.5.2.3, “Consistent Nonlocking Reads”.
    • For locking reads (SELECT with FOR UPDATE or LOCK IN SHARE MODE), UPDATE, and DELETE statements, locking depends on whether the statement uses a unique index with a unique search condition, or a range-type search condition.
    • 对于锁定读(SELECT with FOR UPDATE or LOCK IN SHARE MODE),UPDATE 和DELETE语句, 锁定取决于该语句是使用具有唯一搜索条件的唯一索引还是范围类型搜索条件。
      • For a unique index with a unique search condition, InnoDB locks only the index record found, not the gap before it.
      • 对于具有唯一搜索条件的唯一索引,innodb只锁定找到的索引记录,而不会锁定它之前的间隙
      • For other search conditions, InnoDB locks the index range scanned, using gap locks or next-key locks to block insertions by other sessions into the gaps covered by the range. For information about gap locks and next-key locks, see Section 14.5.1, “InnoDB Locking”.
      • 对于其他搜索条件,InnoDB锁定扫描的索引范围,使用gap locks 或 next-key locks 来阻止其他会话插入到范围所涵盖的间隙中

#READ COMMITTED (读提交)

  • Each consistent read, even within the same transaction, sets and reads its own fresh snapshot. For information about consistent reads, see Section 14.5.2.3, “Consistent Nonlocking Reads”.
  • 每一个一致读,即使在同一事务中,都会设置并读取它自己的新快照,关于一致读的更多详细信息,请看Section 14.5.2.3, “Consistent Nonlocking Reads”.
  • For locking reads (SELECT with FOR UPDATE or LOCK IN SHARE MODE), UPDATE statements, and DELETE statements, InnoDB locks only index records, not the gaps before them, and thus permits the free insertion of new records next to locked records. Gap locking is only used for foreign-key constraint checking and duplicate-key checking.
  • 对于锁定读(SELECT with FOR UPDATE or LOCK IN SHARE MODE),UPDATE 和 DELETE语句,innodb只会针对索引记录加锁,而不会锁定它之前的间隙,从而允许在锁定记录旁边自由插入新记录,间隙锁定仅用于外键约束检查和重复密钥检查。
  • Because gap locking is disabled, phantom problems may occur, as other sessions can insert new rows into the gaps. For information about phantoms, see Section 14.5.4, “Phantom Rows”.
  • 因为间隙锁是被禁止的,如果其他会话在间隙中插入新的一行就有可能发生幻读问题,更多信息请看Section 14.5.4, “Phantom Rows”
  • If you use READ COMMITTED, you must use row-based binary logging.
  • 如果你使用READ COMMITTED隔离级别,必须使用基于行的二进制日志记录。
  • Using READ COMMITTED has additional effects:
  • 使用READ COMMITTED有额外的影响:
    • For UPDATE or DELETE statements, InnoDB holds locks only for rows that it updates or deletes. Record locks for nonmatching rows are released after MySQL has evaluated the WHERE condition. This greatly reduces the probability of deadlocks, but they can still happen.
    • 针对UPDATE或者DELETE语句,InnoDB仅为更新或删除的行保存锁,在MySQL对WHERE条件进行评估后,将会释放用于非匹配行的记录锁。这大大降低了死锁的可能性,但是仍然会发生。
    • For UPDATE statements, if a row is already locked, InnoDB performs a “semi-consistent” read, returning the latest committed version to MySQL so that MySQL can determine whether the row matches the WHERE condition of theUPDATE. If the row matches (must be updated), MySQL reads the row again and this time InnoDB either locks it or waits for a lock on it.
    • 针对update语句,如果某一行已经被加锁了,InnoDB执行“半一致”读,返回mysql最新提交的版本,因此,MySQL可以确定该行是否匹配UPDATE的WHERE件,如果行匹配(必须更新),MySQL再次读取该行,这一次InnoDB要么锁定它,要么等待它的锁。
  • Consider the following example, beginning with this table:
  • 考虑下面的示例,从这个表开始
  • CREATE TABLE t (a INT NOT NULL, b INT) ENGINE = InnoDB;INSERT INTO t VALUES (1,2),(2,3),(3,2),(4,3),(5,2);COMMIT;
  • In this case, table has no indexes, so searches and index scans use the hidden clustered index for record locking (seeSection 14.8.2.1, “Clustered and Secondary Indexes”).
  • 在这个案例中,表没有任何索引,因此,搜索和索引扫描使用隐藏的聚集索引来加上记录锁
  • Suppose that one client performs an UPDATE using these statements:
  • 假设有一个客户端执行了一条这样的UPDATE语句
  • ##session A
  • START TRANSACTION;UPDATE t SET b = 5 WHERE b = 3;
  • Suppose also that a second client performs an UPDATE by executing these statements following those of the first client:
  • 假设第二个客户端在第一个客户端后面执行了这样的一条UPDATE语句
  • ##ession B
  • UPDATE t SET b = 4 WHERE b = 2;
  • As InnoDB executes each UPDATE, it first acquires an exclusive lock for each row, and then determines whether to modify it. If InnoDB does not modify the row, it releases the lock. Otherwise, InnoDB retains the lock until the end of the transaction. This affects transaction processing as follows.
  • 当InnoDB执行每个UPDATE时,它首先获取每行的排它锁,然后确定是否修改它。,如果InnoDB不修改这行,锁将被释放,否则,innodb会保存锁直到事务结束,这将影响接下来的事务
  • When using the default REPEATABLE READ isolation level, the first UPDATE acquires x-locks and does not release any of them:
  • 如果使用默认隔离级别 REPEATABLE READ ,第一个update语句会针对这些行获得排他锁并且不会释放,
    • 14.5.2.1 Transaction Isolation Levels
  • The second UPDATE blocks as soon as it tries to acquire any locks (because first update has retained locks on all rows), and does not proceed until the first UPDATE commits or rolls back:
  • 第二个UPDATE 在试图获取任何锁时就会阻塞(因为第一个update保留了所有行上的锁),直到第一个UPDATE提交或回滚时才进行更新:
    • 14.5.2.1 Transaction Isolation Levels
  • If READ COMMITTED is used instead, the first UPDATE acquires x-locks and releases those for rows that it does not modify:
  • 如果使用的隔离级别是READ COMMITTED,那么第一个UPDTE语句会针对每一行加上锁,然后不需要修改的行上面的锁将会被释放
    • 14.5.2.1 Transaction Isolation Levels
  • For the second UPDATE, InnoDB does a “semi-consistent” read, returning the latest committed version of each row to MySQL so that MySQL can determine whether the row matches the WHERE condition of the UPDATE:
  • 然后看二个UPDATE,innodb使用半一致读,返回mysql最新提交版本的数据,因此,mysql可以确定哪些行符合当前UPDATE的WHERE条件
    • 14.5.2.1 Transaction Isolation Levels
  • However, if the WHERE condition includes an indexed column, and InnoDB uses the index, only the indexed column is considered when taking and retaining record locks. In the following example, the first UPDATE takes and retains an x-lock on each row where b = 2. The second UPDATE blocks when it tries to acquire x-locks on the same records, as it also uses the index defined on column b.
  • 但是,如果WHERE条件包含索引列,并且InnoDB使用索引,则在获取和保留记录锁时仅考虑索引列。 在下面的示例中,第一个UPDATE在b = 2的每一行上都会获取并保留一个x锁。第二个UPDATE在尝试获取相同记录上的x锁时阻塞,因为它也使用在列b上定义的索引。
    • 14.5.2.1 Transaction Isolation Levels
  • The effects of using the READ COMMITTED isolation level are the same as enabling the deprecated innodb_locks_unsafe_for_binlog configuration option, with these exceptions:
  • 使用READ COMMITTED隔离级别的效果与启用过时的innodb_locks_unsafe_for_binlog 配置选项相同,除了以下例外
    • Enabling innodb_locks_unsafe_for_binlog is a global setting and affects all sessions, whereas the isolation level can be set globally for all sessions, or individually per session.
    • innodb_locks_unsafe_for_binlog是一个全局设置,影响所有会话,而隔离级别可以在所有会话中全局设置,也可以在每个会话中单独设置。
  • innodb_locks_unsafe_for_binlog can be set only at server startup, whereas the isolation level can be set at startup or changed at runtime.
  • innodb_locks_unsafe_for_binlog只能服务器启动时设置,而隔离级别可以启动时设置或在运行时更改
  • READ COMMITTED therefore offers finer and more flexible control than innodb_locks_unsafe_for_binlog.
  • READ COMMITTED因此提供了比innodb_locks_unsafe_for_binlog更精细和更灵活的控制。

#READ UNCOMMITTED 读未提交

  • SELECT statements are performed in a nonlocking fashion, but a possible earlier version of a row might be used. Thus, using this isolation level, such reads are not consistent. This is also called a dirty read. Otherwise, this isolation level works like READ COMMITTED
  • SELECT语句是在一个非锁定的方式进行,但是有可能会使用更早版本的行数据,因此,使用这个隔离级别,读不是一致的,称之为脏读,否则,此隔离级别工作机制类似于READ COMMITTED。

#SERIALIZABLE (序列化)

  • This level is like REPEATABLE READ, but InnoDB implicitly converts all plain SELECT statements to SELECT ... LOCK IN SHARE MODE if autocommit is disabled. If autocommit is enabled, the SELECT is its own transaction. It therefore is known to be read only and can be serialized if performed as a consistent (nonlocking) read and need not block for other transactions. (To force a plain SELECT to block if other transactions have modified the selected rows, disable autocommit.)
  • 这个级别有点像REPEATABLE READ,但是innodb隐式的将所有SELECT语句传唤成SELECT ... LOCK IN SHARE MODE除了autocommit 被禁止这种情况,如果启用autocommit,则SELECT是它自己的事务。 因此它被认为是只读的,并且如果作为一致读(非锁定的)执行,则可以被序列化,并且不需要阻塞其他事务(如果其他事务已修改选定的行,强制普通SELECT阻塞,禁用 autocommit.。)

PREV:14.5.2 InnoDB Transaction Model https://blog.51cto.com/itzhoujun/2354184
NEXT: 14.5.2.2 autocommit, Commit, and Rollback https://blog.51cto.com/itzhoujun/2354193

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章