`
todd_liu
  • 浏览: 66012 次
  • 性别: 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的四种事务隔离级别

    2. 在读已提交隔离级别中,事务只能读取已经提交的数据,解决了脏读问题,但事务中的数据读取可能会出现不一致的情况,即不可重复读。 3. 在可重复读隔离级别中,事务多次读取同一数据时,即使其他事务已经提交了对...

    脏读不可重复读幻影读

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

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

    在并发事务处理过程中,可能会出现更新丢失、脏读、不可重复读和幻读等问题。这些问题都是由于多事务并发执行引起的,需要通过事务隔离机制和锁机制来解决。 事务隔离级别 数据库的事务隔离级别是用来解决读一致性...

    mysql事务隔离级别1

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

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

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

    详解Mysql事务隔离级别与锁机制.doc

    事务隔离级别是数据库系统中的一种机制,用于解决多事务并发问题,包括脏写、不可重复读、幻读等问题。锁机制是数据库系统中的一种机制,用于解决数据并发访问的一致性问题。 一、事务及其ACID属性 事务是一个逻辑...

    MySQL事务隔离级别详解.docx

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

    mysql数据库事务隔离级别借鉴.pdf

    - **可重复读(Repeatable Read)**:MySQL的默认隔离级别,它保证在同一事务内多次读取相同数据的结果一致,防止了脏读和不可重复读,但在某些情况下仍可能出现幻读。 - **串行化(Serializable)**:最高的隔离...

    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)**:事务在整个事务期间可以多次读取同一数据并保持一致,...

    SQL中 各种事务级别 和 脏读 不可重复读 幻读问题代码示例

    该资源详细介绍了MySQL数据库中的事务隔离级别,包括读未提交(Read Uncommitted)、读已提交(Read Committed)、可重复读(Repeatable Read)和串行化(Serializable),并讨论了这些级别如何影响脏读、不可重复读...

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

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

    深入理解Mysql锁与事务隔离级别1

    3. 可重复读(REPEATABLE READ):同一事务内多次读取相同数据结果一致,防止脏读和不可重复读,但在某些情况下可能出现幻读。 4. 串行化(SERIALIZABLE):最高等级,所有事务按顺序执行,防止所有并发问题,但性能...

Global site tag (gtag.js) - Google Analytics