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 锁定读:的更多相关文章

  1. 14.3.2.4 Locking Reads 锁定读

    14.3.2.4 Locking Reads 锁定读 如果你的查询数据,然后插入或者更新相关的数据 在同一个事务, 普通的SELECT 语句不足以给予足够保护. 其他事务可以更新或者删除相同的你要查询 ...

  2. 一步一步学MySQL-一致性非锁定读和锁定读

    一致性非锁定读(consistent nonlocking read) 一致性非锁定读是值InnoDB存储引擎通过多版本控制(multi versioning)的方式来读取当前执行时间数据库中的数据. ...

  3. SELECT ... FOR UPDATE or SELECT ... FOR SHARE Locking Reads session

    小结: 1.注意使用限制 Locking reads are only possible when autocommit is disabled (either by beginning transa ...

  4. 转 MYSQL SELECT ... FOR UPDATE and SELECT ... LOCK IN SHARE MODE Locking Reads

    原文: http://dev.mysql.com/doc/refman/5.0/en/innodb-locking-reads.html In some circumstances, a consis ...

  5. Mysql 锁定 读情况

    在一个事务中,标准的SELECT语句是不会加锁,但是有两种情况例外. SELECT ... LOCK IN SHARE MODE SELECT ... FOR UPDATE SELECT ... LO ...

  6. 14.3.2.1 Transaction Isolation Levels 事务隔离级别

    14.3.2 InnoDB Transaction Model InnoDB 事务模型 14.3.2.1 Transaction Isolation Levels 事务隔离级别 14.3.2.2 au ...

  7. SELECT ... LOCK IN SHARE MODE和SELECT ... FOR UPDATE locks在RR模式下可以看到最新的记录

    14.5.2.4 Locking Reads 锁定读: 如果你查询数据然后插入或者修改相关数据在相同的事务里, 常规的SELECT 语句不能给予足够的保护. 其他事务可以修改或者删除你刚查询相同的记录 ...

  8. MySQL SELECT语法(一)SELECT语法详解

    源自MySQL 5.7 官方手册:13.2.9 SELECT Syntax SELECT的语法如下: SELECT [ALL | DISTINCT | DISTINCTROW ] [HIGH_PRIO ...

  9. MySQL error : Deadlock found when trying to get lock; try restarting transaction

    在使用 MySQL 时,我们有时会遇到这样的报错:“Deadlock found when trying to get lock; try restarting transaction”. 在 14. ...

随机推荐

  1. 在进行页面的DIV CSS排版时,遇到IE6(当然有时Firefox下也会偶遇)浏览器中的图片元素img下出现多余空白的问题绝对是常见的对于该问题的解决方法也是“见机行事”。

    当一个img标签没得图片时,在firox中,即使给img标签设置了固定高度和宽度,img标签还是不会站位: 解决方法一:直接将img设置为块状元素:即,设置img为“display:block;”.在 ...

  2. 最近的两个小项目,2:Python webapp的docker镜像

    时间过得真快,一眨眼一个多月没更新了,但这一个月我可没偷懒啊,真的是忙.粘上两篇ReadMe勉强凑合一下,保持博客更新是好习惯. 基于Flask框架,uwsgi起服务,supervisor做管理,应该 ...

  3. HDU 4288 Coder(线段树)

    题意: 给定三种操作 1. add x 向序列中添加x,添加之后序列还保持有序 2. del x  删除序列中值为x的元素 3. sum  求下边模5等于3的元素和 思路: 直接暴力也可以过,就是看暴 ...

  4. 关于在MDK4.5以上版本不能使用JLINK V8的解决办法

    如果安装MDK4.50版本以上不能使用jlink8的话,请安装jlink 4.36k版本(或以下)驱动,安装完成后,把\SEGGER\JLinkARM_V436k目录下的JLinkARM.dll拷贝到 ...

  5. 前台之boostrap

    这个网址有些东西不错

  6. c# 操作.config中AppSettings配置节

    ConfigurationSettings.AppSettings[key].ToString(); 这种方式很眼熟吧? 不过这种方式基本过时了,虽然还能用. 微软建议采用ConfigurationM ...

  7. if elsif;报错;new赋值

    1. IF INSERTING THEN          BEGIN 中间不能为空          END;ELSIF DELETING THEN         BEGIN          E ...

  8. CentOS下的svn强制用户提交时写日志

    问题:在项目提交时候不写日志,在后期查看修改历史时需要对比版本才知道提交原因.解决方案:在svn服务端通过hooks在提交时强制要求写日志.#!/bin/shREPOS="$1"T ...

  9. cocos2d-x学习之类型转换(转)

    在做数据转换时,最好包含以下头文件 #include <iostream> #include <cmath> #include <string> #include  ...

  10. I/O多路复用之poll

    poll函数和select函数非常相似,但是函数接口不一样. #include <poll.h> int poll(struct pollfd *fdarray, unsigned lon ...