14.3.2.4 Locking Reads 锁定读
如果你的查询数据,然后插入或者更新相关的数据 在同一个事务,
普通的SELECT 语句不足以给予足够保护。
其他事务可以更新或者删除相同的你要查询的记录,InnoDB 支持2种类型的锁定读,提供额外的安全:
1.SELECT ... LOCK IN SHARE MODE 设置一个共享的lock 在任何被读取的记录上。
其他会话可以读记录, 但是不能修改它们直到你的事务提交。
如果这些行中的任何记录被其他会话修改,而没有提交,
你的查询等待直到事务结束,然后使用最新的值。
Session 1:
mysql> update t5 set id=200 where id=2;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
Session 2:
mysql> select * from t5 LOCK IN SHARE MODE;--Hang
对于index records 搜索遇到的,, SELECT ... FOR UPDATE 锁定记录和相关的index entries,
和你执行一个UPDATE 语句一样。其他的事务会被更新堵塞,
SELECT ... LOCK IN SHARE MODE,或者读取数据在某个事务隔离级别。
一致性读忽略任何locks 设置在记录上(老本本的记录不会被锁定,它们是通过应用undo logs 来构建)
那些语句是有用的当处理树形结构或者结构化数据,
无论是在单个表里 或者 分散到多个表。
你遍历边缘或者树的分支从一个地方到另一个地方
所有的锁通过LOCK IN SHARE MODE and FOR UPDATE 查询会被释放当事务提交或者回滚
注意:
锁定记录 使用 SELECT FOR UPDATE 只应用在当自动提交关闭时(或者通过开始事务 START TRANSACTION
或者 setting autocommit to 0 如果自动提交被启用,匹配的记录不会被锁定
测试:
mysql> show variables like '%commit%';
+--------------------------------+-------+
| Variable_name | Value |
+--------------------------------+-------+
| autocommit | ON
CREATE TABLE `t5` (
`sn` int(11) NOT NULL AUTO_INCREMENT,
`id` int(11) DEFAULT NULL,
`info` varchar(40) DEFAULT NULL,
PRIMARY KEY (`sn`),
UNIQUE KEY `t5_idx1` (`id`)
)
自动提交开启情况下:
Session 1:
mysql> select * from t5;
Empty set (0.00 sec)
mysql> insert into t5(id,info) values(1,'a1');
Query OK, 1 row affected (0.00 sec)
Session 2:
mysql> select * from t5;
+----+------+------+
| sn | id | info |
+----+------+------+
| 1 | 1 | a1 |
+----+------+------+
1 row in set (0.00 sec)
mysql>
自动提交
/***手工开启事务:
Session 1:
mysql> START TRANSACTION ;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into t5(id,info) values(2,'a2');
Query OK, 1 row affected (0.00 sec)
Session 2:
mysql> select * from t5;
+----+------+------+
| sn | id | info |
+----+------+------+
| 1 | 1 | a1 |
+----+------+------+
1 row in set (0.00 sec)
看不到之前的修改
使用例子:
假设你需要插入一条新的记录到一个子表, 确保子表的记录在父表中也有。
你的应用代码可以确保在整个操作过程中引用的完整性。