mysql事务隔离级别以及有问题的读取(脏读,不可重复读,幻象读)


1.事务里一些有问题的读取:脏读,不可重复读,幻象读

脏读 (dirty read)事务T1更新了一行记录的内容,但是并没有提交所做的修改。事务T2读取更新后的行,然后T1执行回滚操作,取消了刚才所做的修改。现在T2所读取的行就无效了。

不可重复读取 (nonrepeatable read)事务T1读取一行记录,紧接着事务T2修改 了T1刚才读取的那一行记录。然后T1又再次读取这行记录,发现与刚才读取的结果不同。这就称为“不可重复”读,因为T1原来读取的那行记录已经发生了变化。

幻像读取 (phantom read)事务T1读取一条指定的WHERE子句所返回的结果集。然后事务T2新插入 一行记录,这行记录恰好可以满足T1所使用的查询条件中的WHERE 子句的条件。然后T1又使用相同的查询再次对表进行检索,但是此时却看到了事务T2刚才插入的新行。这个新行就称为“幻像”,因为对T1来说这一行就像突 然出现的一样。

2.事务的隔离级别

从级别低到高依次为:

READ UNCOMMITTED 幻像读、不可重复读和脏读都允许。

READ COMMITTED 允许幻像读、不可重复读,但不允许脏读。

REPEATABLE READ 允许幻像读,但不允许不可重复读和脏读。InnoDB默认级别

SERIALIZABLE 幻像读、不可重复读和脏读都不允许。

但是InnoDB的可重复读隔离级别和其他数据库的可重复读是有区别的,不会造成幻象读(phantom read)。

ORACLE数据库支持 READ COMMITTED 和 SERIALIZABLE ,不支持 READ UNCOMMITTED 和 REPEATABLE READ 。

3.测试:

1)并发更新 ,表tab1 的一条记录id=1 num=1,两个session分别执行事务1,2

分别输入下面的语句

事务1 (session1) :

           start transaction;

           update tab1 set num=num+1 where id=1;

=========

一条记录被更新,select发现num=2;

事务2 (session2):

           start transaction;

           update tab1 set num=num+1 where id=1;

=========

事务2会被阻塞,然后session1输入commit;提交事务1。此时事务2更新成功。

session1 select一下会发现num还是2(不允许脏读 );session2 select 一下 num 为3(update可以得到最新提交过的数据然后更新,但是如果没有update,一直是select 的话select得到的num一直是1 ),然后commit;

session1 select 发现num为3 ,session2 select 发现num为3;

所以,事务中update是有行写锁(排他锁)的,不会发生: 脏读和不可重复读(对于自身有update的事务,update之后是可以读到最新数据的,这属于例外?^_^ ),

2)关于幻象读 ,innodb默认事务隔离级别是不会出现的;摘自网上,测试通过:

mysql> set autocommit=off;
Query OK, 0 rows affected (0.00 sec)

session 1 创建表并插入测试数据

mysql> create table test(i int) engine=innodb;
Query OK, 0 rows affected (0.00 sec)

mysql> insert into test values(1);
Query OK, 1 row affected (0.00 sec)
session 2 查询,没有数据,正常,session1没有提交,不允许脏读

mysql> select * from test;
Empty set (0.00 sec)
session 1 提交事务

mysql> commit;
Query OK, 0 rows affected (0.00 sec)
session 2 查询,还是没有数据,没有产生幻象读

mysql> select * from test;
Empty set (0.00 sec)
4.最后,现在应该知道数据库并发控制并不复杂,交给数据库的事务就行,mysql 选用innodb引擎,不会出现:“不可重复读”(就是在事务1进行数据修改的时候,事务2读取的数据是没修改 之前的数据,事务1提交的时候,事务2再次读取的时候得到的是修改后的数据,单个事务内所读数据不一致),“脏读”,“幻象读”;

 关于innodb锁机制的详细解释,参见《mysql手册》-“15.2.10 .  InnoDB 事务模型和锁定”。


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/todd_liu/archive/2010/09/10/5875650.aspx

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
脏读是指一个事务可以读取到另一个事务提交的数据。不可重复读是指在一个事务内多次读取同一数据时,由于其他事务的修改导致每次读取的结果不一致。幻是指在一个事务内多次执行相同的查询,由于其他事务的插入或删除导致每次查询的结果不一致。 在MySQL事务隔离级别对应的脏读不可重复读和幻的情况如下: - 提交(READ UNCOMMITTED)级别下存在脏读不可重复读和幻问题。 - 提交(READ COMMITTED)级别下不存在脏读问题,但仍可能存在不可重复读和幻问题。 - 可重复(REPEATABLE READ)级别下不存在脏读不可重复读问题,但仍可能存在幻问题。 - 串行化(SERIALIZABLE)级别下不存在脏读不可重复读和幻问题。 因此,在MySQL脏读不可重复读和幻都是与事务隔离级别密切相关的一致性问题。根据需求和业务场景,可以选择合适的事务隔离级别来解决这些问题。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Mysql-详解脏读不可重复读、幻](https://blog.csdn.net/ahuangqingfeng/article/details/124407846)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [一文搞懂MySQL脏读,幻不可重复读](https://blog.csdn.net/liuqinhou/article/details/126360614)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值