IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    MySQL事务隔离级别介绍及设置

    mckee发表于 2015-06-10 00:34:52
    love 0

    READ UNCOMMITTED(未提交)
    即使没有提交,对其它事务也可见。未提交的数据会引起脏读(Dirty Read)。
    测试流程:
    1、A设置read-uncommitted, start transaction
    2、B执行start transaction,修改一条记录,
    3、A查询记录,得到了以为正确的记录
    4、B回滚。
    问题:A读到了B没有提交的记录,也就是脏读。

    READ COMMITTED(提交读)
    一个从开始直到提交之前所做的任何修改对其它事务都是不可见的。两次同样的查询可能会得到不一样的结果,称为不可重复读(nonrepeatable read)
    测试流程:
    1、A设置read-committed, start transaction
    2、B执行start transaction,修改一条记录,查询记录,记录已经修改成功
    3、A查询记录,结果还是老的记录
    4、B提交事务
    5、A再次查询记录,结果是新的记录。
    问题:两次查询结果不一致,也就是不可重复读问题。

    REPEATABLE READ(可重复读)-MySQL默认的事务隔离级别
    保证了在同一事务中多次读取结果是一致的。但会引起另外一个幻读问题,当某个事务在读取某个范围记录时,另外一个事务在该范围插入和新记录,当之前事务再次读取该范围记录时会产生幻行。
    测试流程:
    1、A设置repeatable-read, start transaction,查询记录,结果是老的记录
    2、B执行start transaction,修改一条记录,查询记录,记录已经修改成功
    3、A查询记录,结果还是老的记录
    4、B提交事务
    5、A再次查询记录,结果还是老的记录。
    问题:可以重复读,A在事务过程中,即使B修改了数据,并且commit,A读取的还是老的数据。即可重复读。
    注意:这里可能会存在一个新的问题,A在事务过程中,B增加一条记录,并提交,导致A的两次读取不一致,会多一条记录,也就是幻影读。InnoDB通过多版本并发控制(MVCC)解决了幻读问题。

    SERIALIZABLE(可串行化)
    强制事务串行执行,但可能导致大量超时和锁争问题。
    测试流程:
    1、A设置serializable, start transaction,查询记录,结果是老的记录
    2、B执行start transaction,修改一条记录,B卡在这里,要等待A完成才行。
    3、A查询记录,结果还是老的记录,A提交。
    4、B的修改操作才进行下去。
    注意:B在等待过程中,会出现lock超时。

    MySQL事务隔离级别总结:
    MySQL事务隔离级别介绍及设置
    MySQL事务隔离级别操作
    查看当前会话隔离级别:

    mysql> select @@tx_isolation;
    +-----------------+
    | @@tx_isolation  |
    +-----------------+
    | REPEATABLE-READ |
    +-----------------+
    1 row in set (0.12 sec)

    查看当前系统隔离级别:
    mysql> select @@global.tx_isolation;
    +-----------------------+
    | @@global.tx_isolation |
    +-----------------------+
    | REPEATABLE-READ       |
    +-----------------------+

    设置隔离级别语法:
    SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE}



沪ICP备19023445号-2号
友情链接