如果某行記錄被事務鎖住了,select ... for update、或select ... for share事務對相同的行加鎖的時候必須等待,直到產生阻塞的事務釋放鎖。
為了避免等待事務釋放鎖定的行,nowait和skip locked選項可以被用於select ... for update或select ... for share語句:
·nowait:使用了nowait選項的鎖定讀操作,會立即執行,如果讀的記錄被鎖定了就會報錯
·skip locked:使用了skip locked選項的鎖定讀操作,會立即執行,如果讀的記錄被鎖定了就會從結果集移除該記錄。返回的數據是非一致性的。因此,不適用於常規的事務。
nowait和skip locked只適用於行級鎖。
nowait和skip locked對於基於語句的復制是不安全的。
# Session 1: mysql> CREATE TABLE t (i INT, PRIMARY KEY (i)) ENGINE = InnoDB; mysql> INSERT INTO t (i) VALUES(1),(2),(3); mysql> START TRANSACTION; mysql> SELECT * FROM t WHERE i = 2 FOR UPDATE; +---+ | i | +---+ | 2 | +---+ # Session 2: mysql> START TRANSACTION; mysql> SELECT * FROM t WHERE i = 2 FOR UPDATE NOWAIT; ERROR 3572 (HY000): Do not wait for lock. # Session 3: mysql> START TRANSACTION; mysql> SELECT * FROM t FOR UPDATE SKIP LOCKED; +---+ | i | +---+ | 1 | | 3 | +---+