`
todd_liu
  • 浏览: 66948 次
  • 性别: Icon_minigender_1
  • 来自: 江苏
社区版块
存档分类
最新评论

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 COMMITTEDSERIALIZABLE,不支持 READ UNCOMMITTEDREPEATABLE 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.10InnoDB事务模型和锁定”。

分享到:
评论

相关推荐

    MySQL事务隔离级别

    MySQL默认的事务隔离级别是可重复读,它能防止脏读和不可重复读。在这个级别下,事务在整个事务期间可以看到一致的数据视图,即同一查询始终返回相同的结果,除非事务自己对数据进行了修改。然而,幻读问题依然存在...

    MySQL事务隔离级别详解

    在此隔离级别下,一个事务只能读取到其他事务已经提交的数据,可以避免脏读,但会出现不可重复读(Nonrepeatable Read),即在同一事务中,相同查询的结果可能不同。 3. **REPEATABLE-READ(可重复读)** 这种隔离...

    脏读不可重复读幻影读

    不同的事务隔离级别对脏读、不可重复读和幻读有不同的影响。根据ISO/IEC标准,事务隔离级别包括: 1. **READ UNCOMMITTED**(读未提交): - **脏读**、**不可重复读**、**幻读**都可能发生。 - **特点**:并发...

    mysql事务隔离级别1

    MySQL中的事务隔离级别是数据库管理系统确保事务之间相互独立的重要机制,它主要针对并发操作时可能出现的问题,如脏读、不可重复读和幻读等。在MySQL的InnoDB存储引擎中,有四种不同的事务隔离级别: 1. **读未...

    52 MySQL是如何支持4种事务隔离级别的?Spring事务注解是如何设置的?l.pdf

    - `Isolation.SERIALIZABLE`:最严格的隔离级别,防止脏读、不可重复读和幻读。 例如,如果需要将事务隔离级别设置为 READ COMMITTED,可以在 `@Transactional` 注解中这样指定: ```java @Transactional...

    MySQL数据库事务隔离级别详解

    在多用户同时访问数据库的情况下,事务隔离级别能够确保数据的一致性和完整性,避免并发操作带来的各种问题,如脏读、不可重复读和幻读。 1. 脏读(Dirty Read): 脏读指的是在一个事务中,事务A读取了事务B还未...

    MySQL事务隔离级别详解.docx

    MySQL事务隔离级别详解 ...事务隔离级别是MySQL数据库并发控制的一种机制,它可以解决脏读、不可重复读和幻读等问题。开发者可以根据实际情况选择合适的隔离级别,以确保数据库的数据一致性和可靠性。

    MY SQL 事务隔离 查询:默认事务隔离级别

    查询:默认事务隔离级别 mysql> select @@tx_isolation;当前会话的默认事务隔离级别 mysql> select @@session.tx_isolation;当前会话的默认事务隔离级别 mysql> select @@global.tx_isolation;全局的事务隔离级别

    深入理解Mysql事务隔离级别与锁机制.pdf

    Read Uncommitted是最低的隔离级别,在这个级别下,一个事务可以读取其他事务未提交的数据,这可能会导致脏读、不可重复读和幻读的问题。 Read Committed是第二个级别,在这个级别下,一个事务只能读取其他事务已经...

    数据库锁(行锁,表锁,共享锁,排他锁)脏读、不可重复读、幻读和事物隔离级别

    1. 读未提交(Read Uncommitted):允许读取未提交的数据,可能导致脏读、不可重复读、幻读。 2. 读提交(Read Committed):仅能读取已提交的数据,避免脏读,但仍可能遇到不可重复读和幻读。 3. 可重复读...

    Mysql事务的隔离性

    **隔离级别**定义了事务并发执行时的隔离程度,即控制一个事务对其他事务的影响,防止脏读、不可重复读和幻读等问题。MySQL支持四种不同的隔离级别: 1. **READ UNCOMMITTED (未提交读)**:最低的隔离级别,允许...

    MySQL数据库:事务隔离级别.pptx

    MySQL提供了下面4种隔离级:序列化(SERIALIZABLE)、可重复读(REPEATABLE READ)、提交读(READ COMMITTED)、未提交读(READ UNCOMMITTED)。 事务隔离级别 语法格式: SET [GLOBAL | SESSION] TRANSACTION ...

    深入理解Mysql事务隔离级别与锁机制.zip

    2. **读已提交(Read Committed)**:事务只能看到其他事务已经提交的数据,避免了脏读,但可能产生不可重复读或幻读。 3. **可重复读(Repeatable Read)**:事务在整个事务期间可以多次读取同一数据并保持一致,...

    mysql数据库事务隔离级别[参照].pdf

    MySQL数据库提供了四种不同的事务隔离级别,它们分别是读未提交(Read Uncommitted)、读已提交(Read Committed)、可重复读(Repeatable Read)以及串行化(Serializable)。每种隔离级别都有其特点,用于权衡数据...

    spring常用数据库事务传播属性和事务隔离级别1

    3. **Isolation.READ_COMMITTED**:每个事务只能读取已经提交的数据,避免了脏读,但可能遇到不可重复读和幻读问题。Oracle 数据库默认使用此级别。 4. **Isolation.REPEATABLE_READ**:防止了脏读和不可重复读,但...

    56 MySQL最牛的RR隔离级别,是如何基于ReadView机制实现的?l.pdf

    MySQL的可重复读(RR)隔离级别是一种重要的事务隔离级别,旨在避免不可重复读和幻读问题,保证事务在并发环境下的一致性。ReadView(读视图)机制是实现这一隔离级别核心手段之一。本文将详细解析MySQL RR隔离级别...

    事务隔离级别 .docx

    在这个最低的隔离级别,一个事务可以读取到其他事务未提交的数据,这可能导致脏读、不可重复读和幻读问题。脏读是指一个事务读取到了另一个事务还未提交的修改,如果那个事务最终回滚,那么读取的数据就是错误的。 ...

    Mysql事务隔离级别原理实例解析

    串行化是最高的隔离级别,它通过强制事务按照序列执行,从而彻底避免了脏读、不可重复读和幻读。代价是并发性能下降,因为每个事务必须等待前一个事务完成。 理解这些隔离级别对于数据库管理员和开发人员来说至关...

    2019-8-7-MySQL的四种事务隔离级别1

    在读已提交级别,脏读被避免,但同一事务内的多次读取可能返回不同结果,产生不可重复读。在可重复读级别,客户端A可以在事务内部看到一致的数据视图,但幻读可能在插入新行时出现。串行化则通过强制事务串行执行来...

Global site tag (gtag.js) - Google Analytics