14.5.2.4 Locking Reads 锁定读:
如果你查询数据然后插入或者修改相关数据在相同的事务里, 常规的SELECT 语句不能给予足够的保护。
其他事务可以修改或者删除你刚查询相同的记录,InnoDB 支持2个锁定读的类型提供额外的安全:
/*******************
测试MYSQL RR 的重复读:
CREATE TABLE `t3` (
`sn` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增编号',
`phoneNo` int(11) DEFAULT NULL,
PRIMARY KEY (`sn`));
mysql> show create table t3;
+-------
+--------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------+
| Table | Create Table
|
+-------
+--------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------+
| t3 | CREATE TABLE `t3` (
`sn` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增编号',
`phoneNo` int(11) DEFAULT NULL,
PRIMARY KEY (`sn`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+-------
+--------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------+
1 row in set (0.00 sec)
Session 1:
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from t3;
+----+---------+
| sn | phoneNo |
+----+---------+
| 1 | 11 |
| 2 | 22 |
+----+---------+
2 rows in set (0.00 sec)
mysql> select * from t3;
+----+---------+
| sn | phoneNo |
+----+---------+
| 1 | 11 |
| 2 | 22 |
+----+---------+
2 rows in set (0.00 sec)
Session 2:
Database changed
mysql> delete from t3 where sn=2;
Query OK, 1 row affected (0.00 sec)
mysql> commit;
Query OK, 0 rows affected (0.00 sec)
此时session 1看到的还是2条 表明RR是重复读
1.SELECT ... LOCK IN SHARE MODE 设置一个共享锁锁定在任何你要读的记录,其他session 只能读取记录,
因为不能修改它们直到你的事务提交。
如果任何其他记录被其他事务改变 没有被提交,你的查询等待直到那个事务借宿 然后使用最新的数据
mysql> select * from t3;
+----+---------+
| sn | phoneNo |
+----+---------+
| 1 | 11 |
| 2 | 22 |
+----+---------+
2 rows in set (0.00 sec)
mysql> select * from t3 LOCK IN SHARE MODE;
+----+---------+
| sn | phoneNo |
+----+---------+
| 1 | 11 |
| 2 | 99 |
+----+---------+
2 rows in set (4.78 sec)
看到的是最新的数据:
mysql> select * from t3;
+----+---------+
| sn | phoneNo |
+----+---------+
| 1 | 11 |
| 2 | 22 |
+----+---------+
2 rows in set (0.00 sec)
mysql> select * from t3 LOCK IN SHARE MODE;
+----+---------+
| sn | phoneNo |
+----+---------+
| 1 | 11 |
| 2 | 99 |
+----+---------+
2 rows in set (0.00 sec)
2.
mysql> select * from t3 where sn=2 for update --看到的也是最新的记录
-> ;
+----+---------+
| sn | phoneNo |
+----+---------+
| 2 | 99 |
+----+---------+
1 row in set (4.26 sec)
mysql>
mysql> select * from t3;
+----+---------+
| sn | phoneNo |
+----+---------+
| 1 | 11 |
| 2 | 22 |
+----+---------+
2 rows in set (0.00 sec)
对于所有搜索遇到, SELECT ... FOR UPDATE locks 锁定记录和任何相关的index entries,
相当于你执行一个update语句对于那些记录。
其他事务是被堵塞的来更新那些记录,做 SELECT ... LOCK IN SHARE MODE,
或者从读取的数据在某些事务隔离级别。
一直读忽略任何锁设置在记录上(老的记录不能被锁定,它们是应用undo log重构的)
当 LOCK IN SHARE MODE and FOR UPDATE 查询的索引锁是被释放放事务是被提交或者回滚
锁定记录用于更新使用SELECT FOR UPDATE 只使用与当autocommit 被关闭(或者开始事务使用START TRANSACTION or by setting
autocommit to 0.
如果自动提交启用,匹配的记录不会被锁定)
使用例子:
假设你需要插入一条新的记录到一个表child,确保child记录有一个parent 记录 在表parent里。
你的应用代码可以确保完整性
首先, 使用一个一致性读来查询表PARENT 校验parent记录的存在,
你可以安全的插入child 记录到表CHILD?
不行,因为一些其他会话可以删除父表记录在你查询和你插入,不会要你知道
为了避免这个潜在的问题,执行SELECT 使用LOCK IN SHARE MODE:
SELECT * FROM parent WHERE NAME = 'Jones' LOCK IN SHARE MODE;
在LOCK IN SHARE MODE 查询返回parent 'Jones',你可以安全的增加child 记录到CHILD 表 然后提交事务。
任何事务尝试获得一个排它锁在可应用的记录在PARENT 表等待直到你完成为止,
也就是说直到数据在所有的表是一个一致性的状态
另外一个例子, 考虑一个整数计数字段在表CHILD_CODES,
用于分配一个唯一的表示到每个表被增加到表CHILD。
不会使用一致性读或者一个共享模式读来读取当前值
在这里,LOCK IN SHARE MODE 不是一个好的解决方法 因为如果2个用户读取counter 在相同时间,
实现读和增量计数器,首先执行一个counter的锁定读 使用FOR UPDATE, 然后增加counter
SELECT counter_field FROM child_codes FOR UPDATE;
UPDATE child_codes SET counter_field = counter_field + 1;
一个SELECT ... FOR UPDATE 读取最新的可用的记录, 设置排它锁在它读取的每行。
14.5.2.4 Locking Reads 锁定读:
转载本文章为转载内容,我们尊重原作者对文章享有的著作权。如有内容错误或侵权问题,欢迎原作者联系我们进行内容更正或删除文章。
上一篇:perl 定义post接口
下一篇:mysq 日期相减
提问和评论都可以,用心的回复会被更多人看到
评论
发布评论
相关文章
-
【MySQL(八)】一致性非锁定读 锁定读 解析
mysql的锁有若干种分类标准,这里看下行锁中的读锁与写锁。读锁即S锁,也叫共享锁,当事\
锁定读 非锁定读 数据 隔离级别 读取数据 -
14.2.2.2 Consistent Nonlocking Reads 一致性非锁定读
14.2.2.2 Consistent No...
数据库 隔离级别 版本控制 提交事务 mysql -
14.2.2 The InnoDB Transaction Model and Locking InnoDB 事务模型和锁定
14.2.2 The InnoDB Tran...
mysql sql 隔离级别 数据 数据库