MySQL InnoDB引擎提供了三种行锁定方式:共享锁(S锁)、排它锁(X锁)和意向锁(IS锁和IX锁)。
共享锁(S锁)是用来保证读取的数据在事务间的一致性。多个事务可以同时获取共享锁定,因为他们都只是读取数据而不做任何修改。但是,一个事务获取了共享锁之后,其他事务便不能再对该行加排它锁。
语法:SELECT ... FOR SHARE
例如,假设有一个表t,其中包含字段a和b。两个事务A和B分别执行以下语句:
事务A:SELECT * FROM t WHERE a=1 FOR SHARE;
事务B:SELECT * FROM t WHERE a=1 FOR SHARE;
由于两个事务使用了共享锁定,所以它们都可以查询到字段a=1的行并读取其数据,但是没有一个事务可以对这些行进行修改操作。如果其中一个事务尝试修改这些行,则需要等待另一个事务释放它的共享锁。
排它锁(X锁)是用来在事务中修改数据的。同一时刻只有一个事务可以获取排它锁。其他非当前事务的读写操作都需要等待排它锁释放。也就是说,如果一个事务A想要对一个行进行修改,那么它必须先获取对应的排它锁,否则就需要等待。
语法:SELECT ... FOR UPDATE
例如,假设有一个表t,其中包含字段a和b。两个事务A和B分别执行以下语句:
事务A:SELECT * FROM t WHERE a=1 FOR UPDATE;
事务B:SELECT * FROM t WHERE a=1 FOR UPDATE;
由于只有一个事务可以获取排它锁,所以事务B需要等待事务A释放排它锁后才能获取它。
意向锁(IS锁和IX锁)是用来在表级别上管理行级别锁的。在获取行级别锁之前,必须先获取表级别上的意向锁,在释放行级别锁之后,也需要同样先释放表级别上的意向锁。
意向锁分为两种类型:IS锁和IX锁。
IS锁意味着一个锁定的事务想要在一个表的行上增加共享锁定。IX锁,是一个锁定事务想要在表的行上增加排它锁。
在关于行的锁定之前,在表上增加一个意向锁。如果一个进程想要取出某行的共享锁定,那么MySQL检查表上是否已有一个意向锁,并检查该锁是否为IS。如果是,那么该进程可以在该行上加共享锁定。如果该表有一个IX意向锁,则MySQL允许进程取出排它锁。同样,如果进程想要取出排它锁,那么MySQL会检查该表上是否有一个IX意向锁。
语法:LOCK IN SHARE MODE
和FOR UPDATE
已经隐含了意向锁。
例如,假设有一个表t,其中包含字段a和b。事务A执行以下语句对表t上锁定:
LOCK TABLE t WRITE;
此时,在事务A释放锁定之前,其他事务T1和T2无法对表t进行任何读写操作,它们会被阻塞。
总之,MySQL InnoDB引擎提供了三种行锁定方式:共享锁(S锁)、排它锁(X锁)和意向锁(IS锁和IX锁)。开发人员可以根据实际需求选择适当的锁定方式以保证数据的一致性和安全性。
本文链接:http://task.lmcjl.com/news/18078.html