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

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