http://blog.csdn.net/dong976209075/article/details/8802778

经验总结:

Python使用MySQLdb数据库后,如使用多线程,每个线程创建一个db链接,然后再各自创建一个游标cursor,其中第一个线程读一个表中数据为空,第二个写入该表一条数据并提交,第一个线程再读该表数据将仍然无法读出。和多数据库的事务级别应该有关系;还可以在第一个读之前先插入一条,将能够读出第二个线程写入并提交过的数据。

转载自:http://blog.csdn.net/alifel/article/details/6548075


一、事务隔离级别

ANSI/ISO SQL标准定义了4中事务隔离级别:未提交读(read uncommitted),提交读(read committed),重复读(repeatable read),串行读(serializable)。

对于不同的事务,采用不同的隔离级别分别有不同的结果。不同的隔离级别有不同的现象。主要有下面3种现在:

1、脏读(dirty read):一个事务可以读取另一个尚未提交事务的修改数据。

2、非重复读(nonrepeatable read):在同一个事务中,同一个查询在T1时间读取某一行,在T2时间重新读取这一行时候,这一行的数据已经发生修改,可能被更新了(update),也可能被删除了(delete)。

3、幻像读(phantom read):在同一事务中,同一查询多次进行时候,由于其他插入操作(insert)的事务提交,导致每次返回不同的结果集。

不同的隔离级别有不同的现象,并有不同的锁定/并发机制,隔离级别越高,数据库的并发性就越差,4种事务隔离级别分别表现的现象如下表:

隔离级别 脏读 非重复读 幻像读
read uncommitted 允许 允许 允许
read committed   允许 允许
repeatable read     允许
serializable      

二、数据库中的默认事务隔离级别

Oracle中默认的事务隔离级别是提交读(read committed)。

对于MySQL的Innodb的默认事务隔离级别是重复读(repeatable read。可以通过下面的命令查看:

mysql> SELECT @@GLOBAL.tx_isolation, @@tx_isolation;

+———————–+—————–+

| @@GLOBAL.tx_isolation | @@tx_isolation  |

+———————–+—————–+

| REPEATABLE-READ | REPEATABLE-READ |

+———————–+—————–+

1 row in set (0.00 sec)

下面进行一下测试

Time Session 1 Session 2
T1 set autocommit=0; set autocommit=0;
T2 mysql> select * from tmp_test;

+——+———+
| id   | version |
+——+———+
|    1 |       1 |
+——+———+

1 row in set (0.00 sec)

 
T3   mysql> update tmp_test set version=2 where id=1;

Query OK, 1 row affected (0.02 sec)

Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from tmp_test;

+——+———+
| id   | version |
+——+———+
|    1 |       2 |
+——+———+

1 row in set (0.00 sec)

T4 mysql> select * from tmp_test;

+——+———+
| id   | version |
+——+———+
|    1 |       1 |
+——+———+

1 row in set (0.00 sec)

【说明】
Session 2未提交,看到数据不变,无脏读。

 
T5   commit;
T6 mysql> select * from tmp_test;

+——+———+
| id   | version |
+——+———+
|    1 |       1 |
+——+———+

1 row in set (0.00 sec)

【说明】
Session 2已经提交,还是看到数据不变,即可以重复读。

 
T7 commit;  
T8 mysql> select * from tmp_test;

+——+———+
| id   | version |
+——+———+
|    1 |       2 |
+——+———+

1 row in set (0.00 sec)

【说明】
提交事务,看到最新数据。

 
T9   mysql> insert into tmp_test values(2,1);

Query OK, 1 row affected (0.00 sec)

mysql> select * from tmp_test;

+——+———+
| id   | version |
+——+———+
|    1 |       2 |
|    2 |       1 |
+——+———+

2 rows in set (0.00 sec)

mysql> commit;

Query OK, 0 rows affected (0.00 sec)

T10 mysql> select * from tmp_test;

+——+———+
| id   | version |
+——+———+
|    1 |       2 |
+——+———+

1 row in set (0.00 sec)

【说明】
Session 2的insert事务已经提交,看到的数据和T8的时候一样,即未发生幻象读。

 
T11 mysql> commit;

Query OK, 0 rows affected (0.00 sec)

mysql> select * from tmp_test;

+——+———+
| id   | version |
+——+———+
|    1 |       2 |
|    2 |       1 |
+——+———+

2 rows in set (0.00 sec)

【说明】
事务提交,看到最新数据。

 

上面的结果可以看到Innodb的重复读(repeatable read)不允许脏读,不允许非重复读(即可以重复读,Innodb使用多版本一致性读来实现)和不允许幻象读(这点和ANSI/ISO SQL标准定义的有所区别)。

另外,同样的测试:

1、当session 2进行truncate表的时候,这个时候session 1再次查询就看不到数据。

2、当session 2进行alter表的时候,这个时候session 1再次查询就看不到数据。

造成以上的原因是因为 mysql的持续非锁定读,在repeatable read级别下,读采用的是持续非锁定读。相关介绍见下面:

持续读意味着InnoDB使用它的多版本化来给一个查询展示某个时间点处数据库的快照。查询看到在那个时间点之前被提交的那些确切事务做的更改,并且没有其后的事务或未提交事务做的改变。这个规则的例外是,查询看到发布该查询的事务本身所做的改变。

如果你运行在默认的REPEATABLE READ隔离级别,则在同一事务内的所有持续读读取由该事务中第一个这样的读所确立的快照。你可以通过提交当前事务并在发布新查询的事务之后,为你的查询获得一个更新鲜的快照。

持续读是默认模式,在其中InnoDBzai在READ COMMITTED和REPEATABLE READ隔离级别处理SELECT语句。持续读不在任何它访问的表上设置锁定,因此,其它用户可自由地在持续读在一个表上执行的同一时间修改这些表。

注意,持续读不在DROP TABLE和ALTER TABLE上作用。持续读不在DROP TABLE上作用,因为MySQL不能使用已经被移除的表,并且InnoDB 破坏了该表。持续读不在ALTER TABLE上作用,因为它在某事务内执行,该事务创建一个新表,并且从旧表往新表中插入行。现在,当你重新发出持续读之时,它不能在新表中看见任何行,因为它们被插入到一个在持续读读取的快照中不可见的事务 里。

MySQL官方文档中的多版本一致性读中说明了原因:Consistent read does not work over certain DDL statements。

mysql-Innodb事务隔离级别-repeatable read详解的更多相关文章

  1. 数据库常用的事务隔离级别和原理?&&mysql-Innodb事务隔离级别-repeatable read详解

    转载地址:https://baijiahao.baidu.com/s?id=1611918898724887602&wfr=spider&for=pc https://blog.csd ...

  2. mysql-Innodb事务隔离级别-repeatable read详解(转)

    一.事务隔离级别 ANSI/ISO SQL标准定义了4中事务隔离级别:未提交读(read uncommitted),提交读(read committed),重复读(repeatable read),串 ...

  3. mysql-Innodb事务隔离级别-repeatable read详解1

    经验总结: Python使用MySQLdb数据库后,如使用多线程,每个线程创建一个db链接,然后再各自创建一个游标cursor,其中第一个线程读一个表中数据为空,第二个写入该表一条数据并提交,第一个线 ...

  4. 重新学习MySQL数据库8:MySQL的事务隔离级别实战

    重新学习Mysql数据库8:MySQL的事务隔离级别实战 在Mysql中,事务主要有四种隔离级别,今天我们主要是通过示例来比较下,四种隔离级别实际在应用中,会出现什么样的对应现象. Read unco ...

  5. mysql事务之一:MySQL数据库事务隔离级别(Transaction Isolation Level)及锁的实现原理

    一.数据库隔离级别 数据库隔离级别有四种,应用<高性能mysql>一书中的说明: 然后说说修改事务隔离级别的方法: 1.全局修改,修改mysql.ini配置文件,在最后加上 1 #可选参数 ...

  6. MySQL实战 | 03 - 谁动了我的数据:浅析MySQL的事务隔离级别

    原文链接:这一次,带你搞清楚MySQL的事务隔离级别! 使用过关系型数据库的,应该都事务的概念有所了解,知道事务有 ACID 四个基本属性:原子性(Atomicity).一致性(Consistency ...

  7. 一文读懂MySQL的事务隔离级别及MVCC机制

    回顾前文: 一文学会MySQL的explain工具 一文读懂MySQL的索引结构及查询优化 (同时再次强调,这几篇关于MySQL的探究都是基于5.7版本,相关总结与结论不一定适用于其他版本) 就软件开 ...

  8. MySQL之事务隔离级别--转载

    转自:http://793404905.blog.51cto.com/6179428/1615550 本文通过实例展示MySQL事务的四种隔离级别. 1 概念阐述 1)Read Uncommitted ...

  9. 【MySQL】事务隔离级别及ACID

    注:begin或start transaction并不是一个事务的起点,而是在执行它们之后的第一个操作InnoDB表的语句,事务才真正开始.start transaction with consist ...

随机推荐

  1. selenium跳过https的问题

    背景: 周六产品给我反馈:支付成功页面后会提示这个,问自动化为什么没有发现这样的问题 第一反应:这个地址肯定被举报了,我也肯定没有设置过安全链接,因为都没有见过这样的网址,如果有问题,应该会直接出错, ...

  2. 访问虚拟机中web服务的

    经常发现假如我们想弄一点小玩意或跑一些小demo,总是要不断的在自己的工作本本上搭建不同的运行环境,久而久之,本本上充斥着各种软件,速度下降了,同时管理也非常的不方便.于是想到用虚拟机来搭建运行环境, ...

  3. IPv4与IPv6的校验函数

    1. PHP校验IPv4掩码是否合法,在网上搜了下,排名最高的如下, <?php function is_mask($mask){ $bin_mask =(string)decbin(ip2lo ...

  4. Activiti学习记录(五)

    1.排他网关 说明: 1) 一个排他网关对应一个以上的顺序流 2) 由排他网关流出的顺序流都有个conditionExpression元素,在内部维护返回boolean类型的决策结果. 3) 决策网关 ...

  5. 3_HA介绍和安装部署

    一.hadoop 2.x产生背景 1.hadoop 1.x中hdfs和mr在高可用和扩展性等方面存在问题.2.hdfs存在的问题:NN单点故障,难以应用于在线场景:NN压力过大,内存受限,影响系统扩展 ...

  6. java基础面试题:请说出作用域public,private,protected,以及不写时的区别

    不写任何作用域(即访问权限)表示friendly public 公共,权限最大,作用域最大,在类内部.同一package.子孙类.其他package都可以访问 protected保护,在类内部.同一p ...

  7. response.setContentType("text/html;charset=utf-8")后依然乱码的解决方法

    从浏览器获取数据到服务器,服务器将得到数据再显示在浏览器上英文字母正常显示,中文字符乱码的问题,已经使用了 response.setContentType("text/html;charse ...

  8. vi中系统剪切板的设置

    在vi中,如果编译时没有clipboard属性,将vi中的内容拷贝到系统剪切板有些麻烦.可以用如下的方法,查看vi 是否支持系统剪切板的功能: xt@xt-ThinkPad-X220:~$ vi -- ...

  9. 5.7 并行复制配置 基于GTID 搭建中从 基于GTID的备份与恢复,同步中断处理

    5.7 并行复制配置 基于GTID 搭建中从 基于GTID的备份与恢复,同步中断处理 这个文章包含三个部分 1:gtid的多线程复制2:同步中断处理3:GTID的备份与恢复 下面文字相关的东西 大部分 ...

  10. Mysql 查询出某列字段 被包含于 条件数据中

    我们通常是使用  某条件  是否包含于 某列中   ,简单点 就是:select * from 表名 where  字段名 like '%条件数据%'; 现在说下   某列 被包含于 条件数据中 接下 ...