一、前言
关于mysql的不同分布式事务交互存在三种问题:脏读、不可重复读、幻读,mysql根据不同应用场景设置不同的隔离级别(如下表格四种不同隔离级别,每个级别分别对应解决问题说明),默认设置为可重复读(repeatable-read)。
事务隔离级别 | 脏读 | 不可重复读 | 幻读 |
读未提交(read-uncommitted) | 是 | 是 | 是 |
不可重复读(read-committed) | 否 | 是 | 是 |
可重复读(repeatable-read) | 否 | 否 | 是 |
串行化(serializable) | 否 | 否 | 否 |
补充说明
A、事务的基本要素(ACID)@b@@b@ 1、原子性(Atomicity):一个事务必须操作完成,不会停滞在中间环节,执行过程出错,回滚到事务开始前的状态。该事务是一个不可分割的整体-如化学中学过的原子,是物质构成的基本单位。@b@ @b@ 2、一致性(Consistency):事务开始前和结束后,数据库的完整性约束没有被破坏 。比如A向B转账,不可能A扣了钱,B却没收到。@b@ @b@ 3、隔离性(Isolation):同一时刻,只允许一个事务请求同一数据,不同的事务之间彼此没有任何干扰。比如A正在从一张银行卡中取钱,在A取钱的过程结束前,B不能向这张卡转账。@b@ @b@ 4、持久性(Durability):事务完成后,事务对数据库的所有更新将被保存到数据库,不能回滚。@b@ @b@B、事务的并发问题@b@@b@ 1、脏读:事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到的数据是脏数据@b@ @b@ 2、不可重复读:事务A不同阶段多次读取同一数据,事务B在事务A多次读取的过程中,对该数据进行变更,导致事务A多次读取同一数据时,结果不一致。@b@ @b@ 3、幻读:事务A读取到本不该出现事务B提交的新数据,出现貌似幻觉@b@
二、锁表说明
1、事务隔离级别是可重复读时,并不会锁住读取到的行,如果有索引(包括主键索引)的时候,以索引列为条件更新数据,@b@ @b@ 会存在间隙锁间隙锁、行锁、下一键锁的问题,从而锁住一些行;如果没有索引,更新数据时会锁住整张表。@b@@b@2、事务隔离级别为读未提交时,写数据只会锁住相应的行@b@@b@3、事务隔离级别为串行化时,读写数据都会锁住整张表@b@@b@注:隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大。@b@ @b@ 对于多数应用程序,可以优先考虑把数据库系统的隔离级别设为Read Committed,它能够避免脏读取,而且具有较好的并发性能。@b@ @b@ 尽管它会导致不可重复读、幻读这些并发问题,在可能出现这类问题的个别场合,可以由应用程序采用悲观锁或乐观锁来控制。
三、操作配置
方法一、在my.inf文件的[mysqld]节里类似如下设置该选项
transaction-isolation = {READ-UNCOMMITTED | READ-COMMITTED | REPEATABLE-READ | SERIALIZABLE}
方法二、用SET TRANSACTION语句改变单个会话或者所有新进连接的隔离级别。它的语法如下:
SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE}