码迷,mamicode.com
首页 > 数据库 > 详细

mysql事务的隔离级别

时间:2014-11-07 19:23:57      阅读:313      评论:0      收藏:0      [点我收藏+]

标签:mysql事务的隔离级别

1.1.   事务的隔离级别

         ANSI SQL标准制定了四种事务隔离级别,但是很少有数据库厂商遵循这些标准。四个隔离级别为:

级别

名称

说明

1

READ  UNCOMMITTED

被称为浏览访问(browse access),仅仅是对事务而言

2

READ  COMMITTED

被称为游标稳定(cursor stability

3

REPEATABLE  READ

2.99990的隔离,没有幻读保护(innodb默认隔离级别)

4

SERIALIZABLE

被称为隔离,或者30的隔离

          SQLSQL2标准的默认事务隔离级别是SERIALIZABLEINNODB存储引擎与标准SQL不同的是,在REPEATABLE READ事务隔离级别下,使用next-key lock的锁算法,因此避免了幻读的产生,已经能够完全保证事务的隔离性要求,即达到SQL标准的SERIALIZABLE的隔离级别。

         隔离级别越低,事务请求的锁越少或者保持锁的时间越短。这也是为什么大多数数据库系统默认的事务隔离级别是READ COMMITTED的原因。

1.1.1.      隔离级别的设置

         InnoDB存储引擎中,设置隔离级别的语法如下:

         SET [GLOBAL|SESSION] TRANSACTIONISOLATION LEVEL {READ UNCOMMITTED|READ COMMITTED|REPEATABLE READ|SERIALIZABLE}

mysql>set session transaction isolation level read committed;

Query OK,0 rows affected (0.00 sec)

 

mysql>select @@tx_isolation;

+----------------+

|@@tx_isolation |

+----------------+

|READ-COMMITTED |

+----------------+

1 row inset (0.00 sec)

         或者使用参数

         SET tx_isolation = ‘{READ-UNCOMMITTED|READ-COMMITTED|REPEATABLE-READ|SERIALIZABLE}‘;

mysql>set tx_isolation =‘READ-UNCOMMITTED‘;

Query OK,0 rows affected (0.00 sec)

 

mysql>select @@tx_isolation;

+------------------+

|@@tx_isolation   |

+------------------+

|READ-UNCOMMITTED |

+------------------+

1 row inset (0.00 sec)

         在配置文件[mysqld]中的选项为:

         transaction-isolatio = {READ-UNCOMMITTED|READ-COMMITTED|REPEATABLE-READ|SERIALIZABLE}

 

1.1.2.      查看隔离级别

         1)查看当前会话的隔离级别

mysql>select @@tx_isolation;

+-----------------+

|@@tx_isolation  |

+-----------------+

|REPEATABLE-READ |

+-----------------+

1 row inset (0.00 sec)

         2)查看全局的事务隔离级别

mysql>select @@global.tx_isolation;

+-----------------------+

|@@global.tx_isolation |

+-----------------------+

|REPEATABLE-READ       |

+-----------------------+

1 row inset (0.00 sec)

 

1.1.3.      隔离级别的其他注意事项

         (一)SERIALIZABLE事务隔离级别

         SERIALIZABLE的事务隔离级别下,innodb会对每个select语句后自动加上LOCK IN SHARE MODE,即给每个读加一个共享锁。在这个事务隔离级别下,读占用锁了,因此对于一致性的非锁定读不再予以支持。由于innodb存储引擎在REPEATABLE READ隔离级别下就可以达到30的隔离,因此一般不在本地事务中使用SERIALIZABLE隔离级别,SERIALIZABLE隔离级别主要用于INNODB存储引擎的分布式事务。

         (二)READCOMMITTED事务隔离级别

         READCOMMITTED事务隔离级别下,除了唯一性的约束检查及外键约束的检查需要gap lockInnoDB存储引擎不会使用gap lock的锁算法。

         但是使用这个事务隔离级别需要注意一些问题。

         1)隔离级别对二进制日志的影响

         MySQL5.1中,READ COMMITTED事务隔离级别默认只能工作在Replication的二进制日志为Row格式下,如果格式为STATEMENT则会报错。

         MySQL5.0之前的版本不支持Row格式的二进制日志,将参数innodb_locks_unsafe_for_binlog=1来实现可以在二进制日志为STATEMENT下使用READ-COMMITTED的事务隔离级别。

mysql>show variables like ‘innodb_locks_unsafe_for_binlog‘;

+--------------------------------+-------+

|Variable_name                  | Value |

+--------------------------------+-------+

|innodb_locks_unsafe_for_binlog | OFF   |

+--------------------------------+-------+

1 row inset (0.00 sec)

         但是该参数在某些情况下是不安全的,可能会导致masterslave之间数据的不一致。诸如使用该事务级别时,两个事务同时运行, 在第一个事务在删除并没有提交的情况下,第二个事务做了删除条件下的插入数据并提交,在第一个事务提交后,可以看到slave上的数据并没有插入进去。

         原因有两点:

l  READ COMMITTED事务隔离级别下,事务是没有Gap Lock锁的。因此可以在删除条件下插入记录;

l  STATEMENT记录的是MASTER上产生的SQL语句,因此在master服务器上执行的顺序是先删后插,但是在STATEMENT格式中记录的却是先插后删,逻辑上就产生了不一致。

         要避免主从不一致的问题,只需解决上述问题的一个就能保证数据的同步。对于第一种情况,修改隔离级别为REPEATABLE READ事务隔离级别。

         5.1版本之后,支持ROW格式,能够避免第二种情况的发生,但是即使不适用READ COMMITTED的事务隔离级别,也应该考虑将二进制日志的格式更换成ROW,因为这个格式记录的是行的变更,而不是简单的SQL的变更。


mysql事务的隔离级别

标签:mysql事务的隔离级别

原文地址:http://gfsunny.blog.51cto.com/990565/1574052

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!