精华内容
下载资源
问答
  • MySQL设置事务隔离级别

    千次阅读 2019-02-26 20:21:58
    转自:...   修改事务隔离级别的方法: 1.全局修改,修改mysql.ini配置文件,在最后加上 1 #可选参数有:READ-UNCOMMITTED, READ-COMMITTED, REPEATABLE-READ, SERIALIZABLE. 2 [mysqld]...

    转自:https://blog.csdn.net/yangwenxue_admin/article/details/61916140

     

    修改事务隔离级别的方法:

    1.全局修改,修改mysql.ini配置文件,在最后加上

    1 #可选参数有:READ-UNCOMMITTED, READ-COMMITTED, REPEATABLE-READ, SERIALIZABLE.
    2 [mysqld]
    3 transaction-isolation = REPEATABLE-READ

    这里全局默认是REPEATABLE-READ,其实MySQL本来默认也是这个级别

    2.对当前session修改,在登录mysql客户端后,执行命令:

    set session transaction isolation level read uncommitted;

     

    要记住mysql有一个autocommit参数,默认是on,他的作用是每一条单独的查询都是一个事务,并且自动开始,自动提交(执行完以后就自动结束了,如果你要适用select for update,而不手动调用 start transaction,这个for update的行锁机制等于没用,因为行锁在自动提交后就释放了),所以事务隔离级别和锁机制即使你不显式调用start transaction,这种机制在单独的一条查询语句中也是适用的,分析锁的运作的时候一定要注意这一点

     

    再来说说锁机制:
    共享锁:由读表操作加上的锁,加锁后其他用户只能获取该表或行的共享锁,不能获取排它锁,也就是说只能读不能写

    排它锁:由写表操作加上的锁,加锁后其他用户不能获取该表或行的任何锁,典型是mysql事务中

    start transaction;

    select * from user where userId = 1 for update;

    执行完这句以后

      1)当其他事务想要获取共享锁,比如事务隔离级别为SERIALIZABLE的事务,执行

      select * from user;

       将会被挂起,因为SERIALIZABLE的select语句需要获取共享锁

      2)当其他事务执行

      select * from user where userId = 1 for update;

      update user set userAge = 100 where userId = 1; 

      也会被挂起,因为for update会获取这一行数据的排它锁,需要等到前一个事务释放该排它锁才可以继续进行

     

    锁的范围:

    行锁: 对某行记录加上锁

    表锁: 对整个表加上锁

    这样组合起来就有,行级共享锁,表级共享锁,行级排他锁,表级排他锁

     

    下面来说说不同的事务隔离级别的实例效果,例子使用InnoDB,开启两个客户端A,B,在A中修改事务隔离级别,在B中开启事务并修改数据,然后在A中的事务查看B的事务修改效果(两个客户端相当于是两个连接,在一个客户端中的修改参数变量的值是不会影响到另外的一个客户端的):

     

    1.READ-UNCOMMITTED(读取未提交内容)级别

      1)A修改事务级别并开始事务,对user表做一次查询

       

     

      2)B更新一条记录

       

     

      3)此时B事务还未提交,A在事务内做一次查询,发现查询结果已经改变

       

     

      4)B进行事务回滚

       

     

      5)A再做一次查询,查询结果又变回去了

       

     

      6)A表对user表数据进行修改

       

     

      7)B表重新开始事务后,对user表记录进行修改,修改被挂起,直至超时,但是对另一条数据的修改成功,说明A的修改对user表的数据行加行共享锁(因为可以使用select)

       

     

      可以看出READ-UNCOMMITTED隔离级别,当两个事务同时进行时,即使事务没有提交,所做的修改也会对事务内的查询做出影响,这种级别显然很不安全。但是在表对某行进行修改时,会对该行加上行共享锁

     

    2. READ-COMMITTED(读取提交内容)

      1)设置A的事务隔离级别,并进入事务做一次查询

       

     

      2)B开始事务,并对记录进行修改

       

     

      3)A再对user表进行查询,发现记录没有受到影响

       

     

      4)B提交事务

       

     

      5)A再对user表查询,发现记录被修改

       

     

      6)A对user表进行修改

       

     

      7)B重新开始事务,并对user表同一条进行修改,发现修改被挂起,直到超时,但对另一条记录修改,却是成功,说明A的修改对user表加上了行共享锁(因为可以select)

       

       

     

      READ-COMMITTED事务隔离级别,只有在事务提交后,才会对另一个事务产生影响,并且在对表进行修改时,会对表数据行加上行共享锁

     

    3. REPEATABLE-READ(可重读)

      1)A设置事务隔离级别,进入事务后查询一次

       

     

      2)B开始事务,并对user表进行修改

       

     

      3)A查看user表数据,数据未发生改变

       

     

      4)B提交事务

       

     

      5)A再进行一次查询,结果还是没有变化

       

     

      6)A提交事务后,再查看结果,结果已经更新

       

     

      7)A重新开始事务,并对user表进行修改

       

       

      8)B表重新开始事务,并对user表进行修改,修改被挂起,直到超时,对另一条记录修改却成功,说明A对表进行修改时加了行共享锁(可以select)

       

       

     

      REPEATABLE-READ事务隔离级别,当两个事务同时进行时,其中一个事务修改数据对另一个事务不会造成影响,即使修改的事务已经提交也不会对另一个事务造成影响。

      在事务中对某条记录修改,会对记录加上行共享锁,直到事务结束才会释放。

     

    4.SERIERLIZED(可串行化)

      1)修改A的事务隔离级别,并作一次查询

       

     

      2)B对表进行查询,正常得出结果,可知对user表的查询是可以进行的

       

     

      3)B开始事务,并对记录做修改,因为A事务未提交,所以B的修改处于等待状态,等待A事务结束,最后超时,说明A在对user表做查询操作后,对表加上了共享锁

       

     

      SERIALIZABLE事务隔离级别最严厉,在进行查询时就会对表或行加上共享锁,其他事务对该表将只能进行读操作,而不能进行写操作。

    展开全文
  • 查看事务隔离级别MySQL 中,可以通过show variables like ‘%tx_isolation%’或select @@tx_isolation;语句来查看当前事务隔离级别。 查看当前事务隔离级别的 SQL 语句和运行结果如下: mysql> show variables ...
  • MySQL-事务隔离级别设置

    千次阅读 2017-12-25 09:11:32
    先了解下 第一类丢失...撤销一个事务时, 把其他事务已经提交的更新数据覆盖(此情况在事务中不可能出现, 因为一个事务中修改时此记录已加锁, 必须等待此事务完成后另一个事务才可以继续UPDATE) 脏读 一个事务

    加锁研究:http://www.cnblogs.com/JohnABC/p/4377529.html

    先了解下 第一类丢失更新、脏读、不可重复读、幻读、第二类丢失更新

    第一类丢失更新

    撤销一个事务时, 把其他事务已经提交的更新数据覆盖(此情况在事务中不可能出现, 因为一个事务中修改时此记录已加锁, 必须等待此事务完成后另一个事务才可以继续UPDATE)

    脏读

    一个事务读到另一个事务,尚未提交的修改,就是脏读。这里所谓的修改,除了Update操作,不要忘了,还包括Insert和Delete操作。脏读的后果:如果后一个事务回滚,那么它所做的修改,统统都会被撤销。前一个事务读到的数据,就是垃圾数据。

    举个例子:预订房间。

    有一张Reservation表,往表中插入一条记录,来订购一个房间。

    事务1:在Reservation表中插入一条记录,用于预订99号房间。

    事务2:查询,尚未预定的房间列表,因为99号房间,已经被事务1预订。所以不在列表中。

    事务1:信用卡付款。由于付款失败,导致整个事务回滚。 所以插入到Reservation 表中的记录并不置为持久(即它将被删除)。

    现在99号房间则为可用。

    所以,事务2所用的是一个无效的房间列表,因为99号房间,已经可用。如果它是最后一个没有被预定的房间,那么这将是一个严重的失误。

    注:脏读的后果很严重。

    再例如

    时间 取款事务 支票转账事务
    T1 开始事务  
    T2   开始事务
    T3 查询账户余额为1000元  
    T4    
    T5 取出100,把存款余额改为900元  
    T6   查询账户的存款余额为900元(脏读)
    T7 撤销该事务,把存款余额恢复为1000元  
    T8   汇入100元,把存款余额改为1000元
    T9   提交事务

     

    不可重复读

    在同一个事务中,再次读取数据时【就是你的select操作】,所读取的数据,和第1次读取的数据,不一样了。就是不可重复读。

    举个例子:

    事务1:查询有双人床房间。99号房间,有双人床。

    事务2:将99号房间,改成单人床房间。

    事务1:再次执行查询,请求所有双人床房间列表,99号房间不再列表中了。也就是说,事务1,可以看到其他事务所做的修改。

    在不可重复读,里面,可以看到其他事务所做的修改,而导致2次的查询结果不再一样了。这里的修改,是提交过的。也可以是没有提交的,这种情况同时也是脏读。

    如果,数据库系统的隔离级别。允许,不可重复读。那么你启动一个事务,并做一个select查询操作。查询到的数据,就有可能,和你第2次,3次...n次,查询到的数据不一样。一般情况下,你只会做一次,select
    查询,并以这一次的查询数据,作为后续计算的基础。因为允许出现,不可重复读。那么任何时候,查询到的数据,都有可能被其他事务更新,查询的结果将是不确定的。

    注:如果允许,不可重复读,你的查询结果,将是不确定的。一个不确定的结果,你能容忍吗?

    幻读

    事务1读取指定的where子句所返回的一些行。然后,事务2插入一个新行,这个新行也满足事务1使用的查询where子句。然后事务1再次使用相同的查询读取行,但是现在它看到了事务2刚插入的行。这个行被称为幻象,因为对事务1来说,这一行的出现是不可思议的。

    举个例子:

    事务1:请求没有预定的,双人床房间列表。

    事务2:向Reservation表中插入一个新纪录,以预订99号房间,并提交。

    事务1:再次请求有双人床的未预定的房间列表,99号房间,不再位于列表中。

    注:幻读,针对的是,Insert操作。如果事务2,插入的记录,没有提交。那么同时也是脏读。

    第二类丢失更新

    这是不可重复读中的特例, 一个事务覆盖另一个事务已提交的更新数据(以下会出现此情况)

    时间 取款事务 支票转账事务
    T1 开始事务  
    T2   开始事务
    T3 查询账户余额为1000元  
    T4   查询账户余额为1000元
    T5 取出100,把存款余额改为900元  
    T6 提交事务  
    T7   汇入100元,把存款余额改为1100元
    T8   提交事务

     

     

    No 事务1 事务2 备注
    1 select * from tb2 where id=1;
    <NO>    id      name    name2
    1       1       a       a
       
    2   update tb2 set name2='b' where id=1;
    1 Rows updated!
     
    3 select * from tb2 where id=1;
    <NO>    id      name    name2
    1       1       a       a
      很好:没有出现脏读
    4   commit  
    5 select * from tb2 where id=1;
    <NO>    id      name    name2
    1       1       a       a
      很好:没有出现不可重复读
    6 update tb2 set name='a1' where id=1;
    1 Rows updated!
       
    7 select * from tb2 where id=1;
    <NO>    id      name    name2
    1       1       a1      b
      糟糕:name2的值怎么跟以前不一样了。(即出现了不可重复读)
    8 commit    

     

    应该明白 什么状况对什么加什么锁(可以分别思考和测试每个隔离级别下脏读、不可重复读、幻读的出现及不出现原因)

    读完下面的内容可以回头来看此段:

      不可重复读错误处理:通常可以用 set tran isolation level repeatable read 来设置隔离级别, 这样事务 A 在两次读取表T中的数据时, 事务B如果企图更改表T中的数据(细节到事务A读取数据)时, 就会被阻塞, 直到事务A提交! 这样就保证了, 事务A两次读取的数据的一致性

      幻读错误处理:如果设置 repeatable read, 虽然可以防止事务B对数据进行修改, 但是事务B却可以向表T中插入新的数据, 如何防止这个问题, 我们可以考虑设置最高的事务隔离级别 set tran isolation level serializable, 于是乎, 事务B就只能乖乖的等待事务A的提交, 才能向表T中插入新的数据, 从而避免了幻读

     

    不可重复读与幻读的区别:

    脏读的重点是读另一个事务未提交的数据(假若那个事务RollBack, 则这数据就是无效的):某个事务已更新一份数据, 另一个事务在此时读取了同一份数据, 由于某些原因, 前一个RollBack了操作, 则后一个事务所读取的数据就会是不正确的

    不可重复读的重点是修改: 同样的条件, 你读取过的数据, 再次读取出来发现值不一样了

    幻读的重点在于新增或者删除: 同样的条件, 第1次和第2次读出来的记录数不一样

    当然, 从总的结果来看, 似乎两者都表现为两次读取的结果不一致, 但如果你从控制的角度来看, 两者的区别就比较大, 对于不可重复读, 只需要锁住满足条件的记录, 对于幻读, 要锁住满足条件及其相近的记录

     

    rollback;或者commit;都会退出事务!

    更新记录的时候需要锁!

     

    InnoDB中 只要此行在别的事务中产生了锁 本事务中就不允许进行修改 只能阻塞 等待别的事务提交

     

    一般设置为Read Committed, 并且利用悲观锁(SELECT ... FOR UPDATE)或乐观锁(SET NUM=NUM+1, 而不是计算后再插入, 避免并发)来处理特殊情况

     

    SQL标准定义了4类隔离级别,包括了一些具体规则,用来限定事务内外的哪些改变是可见的,哪些是不可见的。低级别的隔离级一般支持更高的并发处理,并拥有更低的系统开销。
    Read Uncommitted(读取未提交内容)

           在该隔离级别,所有事务都可以看到其他未提交事务的执行结果。本隔离级别很少用于实际应用,因为它的性能也不比其他级别好多少。读取未提交的数据,也被称之为脏读(Dirty Read)。
    Read Committed(读取提交内容)

           这是大多数数据库系统的默认隔离级别(但不是MySQL默认的)。它满足了隔离的简单定义:一个事务只能看见已经提交事务所做的改变。这种隔离级别 也支持所谓的不可重复读(Nonrepeatable Read),因为同一事务的其他实例在该实例处理其间可能会有新的commit,所以同一select可能返回不同结果。
    Repeatable Read(可重读)

           这是MySQL的默认事务隔离级别,它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行。不过理论上,这会导致另一个棘手的问题:幻读 (Phantom Read)。简单的说,幻读指当用户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的“幻影” 行。InnoDB和Falcon存储引擎通过多版本并发控制(MVCC,Multiversion Concurrency Control)机制解决了该问题。

    Serializable(可串行化) 
           这是最高的隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。简言之,它是在每个读的数据行上加上共享锁。在这个级别,可能导致大量的超时现象和锁竞争。只要操作产生了锁,就不允许其他事务读取和修改!(可以看看加锁处理分析http://hedengcheng.com/?p=771或者百度网盘http://pan.baidu.com/s/1mgN00Og)

             这四种隔离级别采取不同的锁类型来实现,若读取的是同一个数据的话,就容易发生问题。例如:

             脏读(Drity Read):某个事务已更新一份数据,另一个事务在此时读取了同一份数据,由于某些原因,前一个RollBack了操作,则后一个事务所读取的数据就会是不正确的。

             不可重复读(Non-repeatable read):在一个事务的两次查询之中数据不一致,这可能是两次查询过程中间插入了一个事务更新的原有的数据。

             幻读(Phantom Read):在一个事务的两次查询中数据笔数不一致,例如有一个事务查询了几列(Row)数据,而另一个事务却在此时插入了新的几列数据,先前的事务在接下来的查询中,就会发现有几列数据是它先前所没有的。

             在MySQL中,实现了这四种隔离级别,分别有可能产生问题如下所示:

    隔离级别 是否出现第一类丢失更新 是否出现脏读 是否出现不可重复读 是否出现幻读 是否出现第二类丢失更新
    Serializable
    Repeatable Read
    Read Commited
    Read Uncommited


    下面,将利用MySQL的客户端程序,分别测试几种隔离级别。测试数据库为test,表为tx;表结构:

    id                               int

    num

                                  int

    两个命令行客户端分别为A,B;不断改变A的隔离级别,在B端修改数据。

     

    SET [SESSION|GLOBAL] TRANSACTION ISOLATION LEVEL [READ UNCOMMITTED|READ COMMITTED|REPEATABLE READ|SERIALIZABLE]

     

     

    (一)、将A的隔离级别设置为read uncommitted(未提交读)

     在B未更新数据之前:

    客户端A: 

    B更新数据:

    客户端B:

    客户端A:

            经过上面的实验可以得出结论,事务B更新了一条记录,但是没有提交,此时事务A可以查询出未提交记录。造成脏读现象。未提交读是最低的隔离级别。

    (二)、将客户端A的事务隔离级别设置为read committed(已提交读)

     在B未更新数据之前:

    客户端A:

    B更新数据:

    客户端B:

    客户端A:

           经过上面的实验可以得出结论,已提交读隔离级别解决了脏读的问题,但是出现了不可重复读的问题,即事务A在两次查询的数据不一致,因为在两次查询之间事务B更新了一条数据。已提交读只允许读取已提交的记录,但不要求可重复读。

    (三)、将A的隔离级别设置为repeatable read(可重复读)

     在B未更新数据之前:

    客户端A:

    B更新数据:

    客户端B:

    客户端A:

    B插入数据:

    客户端B:

    客户端A:

           由以上的实验可以得出结论,可重复读隔离级别只允许读取已提交记录,而且在一个事务两次读取一个记录期间,其他事务部的更新该记录。但该事务不要求与其他 事务可串行化。例如,当一个事务可以找到由一个已提交事务更新的记录,但是可能产生幻读问题(注意是可能,因为数据库对隔离级别的实现有所差别)。像以上 的实验,就没有出现数据幻读的问题。

    (四)、将A的隔离级别设置为 可串行化 (Serializable)

    A端打开事务,B端插入一条记录

    事务A端:

    事务B端:

    因为此时事务A的隔离级别设置为serializable,开始事务后,并没有提交,所以事务B只能等待。

    事务A提交事务:

    事务A端

    事务B端

          

          serializable完全锁定字段,若一个事务来查询同一份数据就必须等待,直到前一个事务完成并解除锁定为止 。是完整的隔离级别,会锁定对应的数据表格,因而会有效率的问题。

     

    利用悲观锁

     

     

    时间 取款事务 支票转账事务
    T1 开始事务  
    T2   开始事务
    T3 select * from ACCOUNTS where ID = 1 for update;
    查询账户余额为1000元;这条记录被锁定。
     
    T4   select * from ACCOUNTS where ID = 1 for update;
    执行该语句时,事务停下来等待取款事务解除对这条记录的锁定。
    T5 取出100,把存款余额改为900元  
    T6 提交事务  
    T7   事务恢复运行,查询结果显示存款余额为900.这条记录被锁定。
    T8   汇入100元,把存款余额改为1000元。
    T9   提交事务

     

    用图展示隔离级别及对应缺陷:

      READ UNCOMMITTED 在该隔离级别下,所有事务都可以看到其它未提交事务的执行结果。如下图所示: 

        缺陷:事务2查询到的数据是事务1中修改但未提交的数据,但因为事务1回滚了数据,所以事务2查询的数据是不正确的,因此出现了脏读的问题。

      READ COMMITTED 在该隔离级别下,一个事务从开始到提交之前对数据所做的改变对其它事务是不可见的,这样就解决在READ-UNCOMMITTED级别下的脏读问题。但如果一个事务在执行过程中,其它事务的提交对该事物中的数据发生改变,那么该事务中的一个查询语句在两次执行过程中会返回不一样的结果。如下图所示: 


        缺陷:事务2执行update语句但未提交前,事务1的前两个select操作返回结果是相同的。但事务2执行commit操作后,事务1的第三个select操作就读取到事务2对数据的改变,导致与前两次select操作返回不同的数据,因此出现了不可重复读的问题。

      REPEATABLE READ 这是MySQL的默认事务隔离级别,能确保事务在并发读取数据时会看到同样的数据行,解决了READ-COMMITTED隔离级别下的不可重复读问题。mysql的InnoDB存储引擎通过多版本并发控制(Multi_Version Concurrency Control, MVCC)机制来解决该问题。在该机制下,事务每开启一个实例,都会分配一个版本号给它,如果读取的数据行正在被其它事务执行DELETE或UPDATE操作(即该行上有排他锁),这时该事物的读取操作不会等待行上的锁释放,而是根据版本号去读取行的快照数据(记录在undo log中),这样,事务中的查询操作返回的都是同一版本下的数据,解决了不可重复读问题。其原理如下图所示: 

        缺陷:虽然该隔离级别下解决了不可重复读问题,但理论上会导致另一个问题:幻读(Phantom Read)。正如上面所讲,一个事务在执行过程中,另一个事物对已有数据行的更改,MVCC机制可保障该事物读取到的原有数据行的内容相同,但并不能阻止另一个事务插入新的数据行,这就会导致该事物中凭空多出数据行,像出现了幻读一样,这便是幻读问题。如下图所示:

        缺陷:事务2对id=1的行内容进行了修改并且执行了commit操作,事务1中的第二个select操作在MVCC机制的作用下返回的仍是v=1的数据。但事务3执行了insert操作,事务1第三次执行select操作时便返回了id=2的数据行,与前两次的select操作返回的值不一样。需要说明的是,REPEATABLE-READ隔离级别下的幻读问题是SQL标准定义下理论上会导致的问题,MySQL的InnoDB存储引擎在该隔离级别下,采用了Next-Key Locking锁机制避免了幻读问题。Next-Key Locking锁机制将在后面的锁章节中讲到。

      SERIALIZABLE 这是事务的最高隔离级别,通过强制事务排序,使之不可能相互冲突,就是在每个读的数据行加上共享锁来实现。在该隔离级别下,可以解决前面出现的脏读、不可重复读和幻读问题,但也会导致大量的超时和锁竞争现象,一般不推荐使用。

      转自:http://xm-king.iteye.com/blog/770721

      参考:http://blog.csdn.net/u013235478/article/details/50625602

      更多测试:

        http://blog.csdn.net/wangsifu2009/article/details/6715120

        http://www.2cto.com/database/201412/359238.htm

    展开全文
  • MySQL 四种事务隔离级别详解及对比 按照SQL:1992 事务隔离级别,InnoDB默认是可重复读的(REPEATABLE READ)。MySQL/InnoDB 提供SQL标准所描述的所有四个事务隔离级别。你可以在命令行用–transaction-isolation选项...
  • 数据库事务隔离级别 数据库事务的隔离级别有4个,由低到高依次为 Read uncommitted:允许脏读。 Read committed: 防止脏读,最常用的隔离级别,并且是大多数数据库的默认隔离级别。 Repeatable read:可以防止脏...
  • 主要介绍了MySQL事务及Spring隔离级别实现原理详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
  • MySQL的四种事务隔离级别 一、事务的基本要素(ACID) 1、原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做,不可能停滞在中间环节。事务执行过程中出错,会回滚到事务开始前的状态,所有的...

    MySQL的四种事务隔离级别

    一、事务的基本要素(ACID)

    1、原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做,不可能停滞在中间环节。事务执行过程中出错,会回滚到事务开始前的状态,所有的操作就像没有发生一样。也就是说事务是一个不可分割的整体,就像化学中学过的原子,是物质构成的基本单位。

    2、一致性(Consistency):事务开始前和结束后,数据库的完整性约束没有被破坏 。比如A向B转账,不可能A扣了钱,B却没收到。

    3、隔离性(Isolation):同一时间,只允许一个事务请求同一数据,不同的事务之间彼此没有任何干扰。比如A正在从一张银行卡中取钱,在A取钱的过程结束前,B不能向这张卡转账。

    4、持久性(Durability):事务完成后,事务对数据库的所有更新将被保存到数据库,不能回滚。

    二、事务的并发问题

    1、脏读:事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到的数据是脏数据

    2、不可重复读:事务 A 多次读取同一数据,事务 B 在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果 不一致。

    3、幻读:系统管理员A将数据库中所有学生的成绩从具体分数改为ABCDE等级,但是系统管理员B就在这个时候插入了一条具体分数的记录,当系统管理员A改结束后发现还有一条记录没有改过来,就好像发生了幻觉一样,这就叫幻读。

    小结:不可重复读的和幻读很容易混淆,不可重复读侧重于修改,幻读侧重于新增或删除。解决不可重复读的问题只需锁住满足条件的行,解决幻读需要锁表

    三、MySQL事务隔离级别

    事务的隔离级别分为:

    未提交读(read uncommitted)、已提交读(read committed)、可重复读(repeatable read)、串行化(serializable)

    四种级别由低到高依次为Read uncommitted 、Read committed 、Repeatable read 、Serializable ,这四个级别可以逐个解决脏读 、不可重复读 、幻读 这几类问题。

    : 可能出现 : 不会出现
    在这里插入图片描述
    未提交读

    A事务已执行,但未提交;B事务查询到A事务的更新后数据;A事务回滚;—出现脏数据

    已提交读

    A事务执行更新;B事务查询;A事务又执行更新;B事务再次查询时,前后两次数据不一致;—不可重复读

    可重复读

    A事务无论执行多少次,只要不提交,B事务查询值都不变;B事务仅查询B事务开始时那一瞬间的数据快照;—幻读

    串行化

    不允许读写并发操作,写执行时,读必须等待;

    四、数据库设置

    //查看当前事物级别(mysql8.0以上版本不适用, 请看下面):
    SELECT @@tx_isolation;

    //设置mysql的隔离级别:
    set session transaction isolation level;设置事务隔离级别

    //设置read uncommitted级别:
    set session transaction isolation level read uncommitted;

    //设置read committed级别:
    set session transaction isolation level read committed;

    //设置repeatable read级别:
    set session transaction isolation level repeatable read;

    //设置serializable级别:
    set session transaction isolation level serializable;

    Mysql 8.0+ 查询数据库事务隔离级别

    根据慕课网课程中的方法,查询事务隔离级别使用:

    select @@tx_isolation;

    我在sequal pro中,却提示错误:Unknown system variable ‘tx_isolation’

    查询了官方文档,在8.0+就已经抛弃了这样的查询方法,
    https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html

    在这里插入图片描述
    在MySQL 8.0.3 中,该变量已经被 transaction_isolation 替换了。

    最新的查询方法有多种,下面提供2种:

    1、select @@transaction_isolation;

    在这里插入图片描述

    2、show variables like ‘transaction_isolation’;

    在这里插入图片描述

    展开全文
  • 锁 1、查看表锁, Table_locks_waited较高表明锁争用比较严重 ...8、查看数据库的事务隔离级别 select @@global.tx_isolation, @@session.tx_isolation; 听说,打赏我的人最后都找到了真爱。  

    1、查看表锁, Table_locks_waited较高表明锁争用比较严重

    show status like 'table%'

     

    2、查看行锁,Innodb_row_lock_waits和InnoDB_row_lock_time_avg较高表明锁争用比较严重

    show status like 'innodb_row_lock%'

     

    3、加写表锁(需手动unclock tables,用commit不会自动解锁)

    lock table user write;

     

    4、加读表锁(需手动unclock tables,用commit不会自动解锁)

    lock table user read;

     

    5、加读表锁(需手动unclock tables,用commit不会自动解锁),并支持另一个事务的insert操作

    lock table user read local;

     

    6、加共享行锁(提交事务,自动解锁)

    select * from user where id=2 lock in share mode; 

     

    7、加排他行锁(提交事务,自动解锁)

    delete from user where id=2 for update;

     

    8、其他说明

    INSERT...SELECT...和 CREATE TABLE...SELECT...语句,会锁原表

    set global concurrent_insert=2; -- 设置是否开启并发insert,0=不开启,1=没有空洞的情况下,允许insert,2=不管有没有空洞,都允许插入
    select @@LOW_PRIORITY_UPDATES; -- 默认情况下,写锁比读锁优先级高,所以写锁会先得到锁,用这个命令可以降低写锁的级别
    select @@max_write_lock_count; -- 当写锁达到指定数量,会降低写锁优先级

     


    事务

    1、开启事务

    set autocommit=0; -- 先取消自动事务提交
    start transaction; -- 手动开启事务

     

    2、提交事务(不会自动释放表锁)

    commit;

     

    3、回滚事务

    rollback;

     

    4、设置事务的隔离级别为“未提交读”(可能导致脏读)

     

    set session transaction isolation level read uncommitted;

     

    5、设置事务的隔离级别为“已提交读读”(可能导致不可重复读)

    set session transaction isolation level read committed;

     

    6、设置事务的隔离级别为“可重复读”(可能导致幻读)

    set session transaction isolation level repeatable read;

     

    7、设置事务的隔离级别为“序列化”

    set session transaction isolation level serializable;

     

    8、查看数据库的事务隔离级别

    select @@global.tx_isolation, @@session.tx_isolation;

    听说,打赏我的人最后都找到了真爱。

     

    展开全文
  • mysql的默认的是REPEATABLE-READ variables里默认的是可重复对读REPEATABLE-READ 没有开启事务默认直接commit 开启当前一个事务 begin; 提交当前的事务,提交完关闭当前事务,并使已对数据库进行的所有修改...
  • 作者:伞U ...好久没碰数据库了,只是想起自己当时在搞数据库的...为了说明问题,我们打开两个控制台分别进行登录来模拟两个用户(暂且成为用户 A 和用户 B 吧),并设置当前 MySQL 会话的事务隔离级别。 一. read unco
  • 事务隔离级别分为:未提交读(read uncommitted)、已提交读(read committed)、可重复读(repeatable read)、串行化(serializable)。 未提交读 A事务已执行,但未提交;B事务查询到A事务的更新后数据;A事务回滚...
  • 查看并设置MySQL的事务隔离级别MySQL事务的隔离级别查看MySQL的事务隔离级别设置MySQL的事务隔离级别 MySQL事务的隔离级别 4种事务隔离级别 READ_UNCOMMITTED(读未提交) READ_COMMITTED(读已提交) REPEATABLE_...
  • 查询:默认事务隔离级别 mysql> select @@tx_isolation;当前会话的默认事务隔离级别 mysql> select @@session.tx_isolation;当前会话的默认事务隔离级别 mysql> select @@global.tx_isolation;全局的事务隔离级别
  • MySQL事务隔离级别详解,这个面试经常会面到,必会呀,哈哈
  • 数据库隔离级别有四种,应用《高性能mysql》一书中的说明:然后说说修改事务隔离级别的方法:1.全局修改,修改mysql.ini配置文件,在最后加上#可选参数有:READ-UNCOMMITTED,READ-COMMITTED,REPEATABLE-READ,...
  • MySQL设置事物隔离级别

    万次阅读 2017-03-13 13:21:34
    高性能MySQL学习总结及实验验证: ...然后说说修改事务隔离级别的方法: 1.全局修改,修改mysql.ini配置文件,在最后加上 1 #可选参数有:READ-UNCOMMITTED, READ-COMMITTED, REPEATABLE-READ, SERIALIZABLE. 2
  • 之前在网上查询mysql事务隔离相关资料,一直只是脑子里有一个印象,久而久之还是会忘记,忘记后又要到网上查找相关资料,但是没实践过就对mysql事务隔离级别理解不是特别的深入,现在自己亲手实践体验一下这个这四个...
  • 主要介绍了Mysql事务隔离级别原理实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
  • mysql8.0.16查看并修改事务隔离级别

    千次阅读 2019-09-25 14:54:11
    mysql> select @@version; +-----------+ | @@version | +-----------+ | 8.0.16 | +-----------+ 1 row in set (0.00 sec) mysql> show variables like 'autocommit'; +---------------+-------+ | Va...
  • 查询mysql事务隔离级别

    千次阅读 2019-10-11 16:37:59
    3、事务隔离级别越高,越能保证数据的完整性,但是对并发性能影响大,就比如隔离级别为串行化时,读取数据会锁住整张表。 4、不可重复读和幻读很相似,两者整体上都是两次读的数据不相同,但是不可重复读一般时更新...
  • 主要介绍了MySql四种隔离级别,帮助大家更好的理解和学习MySQL,感兴趣的朋友可以了解下
  • MySQL 8.0 8.0 查询语法: SELECT @@transaction_isolation; 8.0修改语法: SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED; 或 SET transaction_isolation = 'READ-UNCOMMITTED'; 可选项: READ ...
  • 更改MySQL的默认事务隔离级别

    万次阅读 2019-06-01 10:04:07
    MySQL事务隔离级别一共有四个: 大多数的数据库系统的默认事务隔离级别都是:Read committed 而MySQL的默认事务隔离级别是:Repeatable Read 我们可以采用下面这种方法查询Mysql中的当前事务隔离级别: ...
  • Mysql默认的隔离级别为REPEATABLE-READ(不可重复读)。 设置隔离级别的命令为:set session transaction isolation level +隔离级别 设置隔离级别为读取未提交:set session transaction isolation level ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 91,573
精华内容 36,629
关键字:

mysql设置事务隔离级别

mysql 订阅