From : http://blog.csdn.net/mchdba/article/details/12837427

6 事务的隔离级别

设置的目的

数据库操作中,为了有效保证并发读取数据的正确性,提出的事务隔离级别。

数据库是要被广大客户所共享访问的,那么在数据库操作过程中很可能出现以下几种不确定情况。

更新丢失

两个事务都同时更新一行数据,但是第二个事务却中途失败退出,导致对数据的两个修改都失效了。这是因为系统没有执行任何的锁操作,因此并发事务并没有被隔离开来。

脏读

一个事务开始读取了某行数据,但是另外一个事务已经更新了此数据但没有能够及时提交。这是相当危险的,因为很可能所有的操作都被回滚

不可重复读(Non-repeatable Reads)

一个事务对同一行数据重复读取两次,但是却得到了不同的结果。它包括以下情况:

(1) 事务T1读取某一数据后,事务T2对其做了修改,当事务T1再次读该数据时得到与前一次不同的值。

(2) 幻读(Phantom Reads):事务在操作过程中进行两次查询,第二次查询的结果包含了第一次查询中未出现的数据或者缺少了第一次查询中出现的数据(这里并不要求两次查询的SQL语句相同)。这是因为在两次查询过程中有另外一个事务插入数据造成的。

解决方案

为了避免上面出现的几种情况,在标准SQL规范中,定义了4个事务隔离级别,不同的隔离级别对事务的处理不同。

未授权读取

也称为读未提交(Read Uncommitted):允许脏读取,但不允许更新丢失。如果一个事务已经开始写数据,则另外一个事务则不允许同时进行写操作,但允许其他事务读此行数据。该隔离级别可以通过“排他写锁”实现。

授权读取

也称为读提交(Read Committed):允许不可重复读取,但不允许脏读取。这可以通过“瞬间共享读锁”和“排他写锁”实现。读取数据的事务允许其他事务继续访问该行数据,但是未提交的写事务将会禁止其他事务访问该行。

可重复读取

可重复读取(Repeatable Read):禁止不可重复读取和脏读取,但是有时可能出现幻影数据。这可以通过“共享读锁”和“排他写锁”实现。读取数据的事务将会禁止写事务(但允许读事务),写事务则禁止任何其他事务。

序列化

序列化(Serializable):提供严格的事务隔离。它要求事务序列化执行,事务只能一个接着一个地执行,但不能并发执行。如果仅仅通过“行级锁”是无法实现事务序列化的,必须通过其他机制保证新插入的数据不会被刚执行查询操作的事务访问到。

隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大。对于多数应用程序,可以优先考虑把数据库系统的隔离级别设为Read Committed。它能够避免脏读取,而且具有较好的并发性能。尽管它会导致不可重复读、虚读和第二类丢失更新这些并发问题,在可能出现这类问题的个别场合,可以由应用程序采用悲观锁乐观锁来控制。

在MySQL中设置事务隔离级别有2种方法:

1 在my.cnf中设置,在mysqld选项中如下设置

[mysqld]

transaction-isolation = READ-COMMITTED

2 在mysql窗口用set命令重置

  1. mysql> set global tx_isolation='REPEATABLE-READ';
  2. Query OK, 0 rows affected (0.01 sec)
  3. mysql>

查询当前的会话事务级别,可以使用:

  1. mysql> select @@tx_isolation;
  2. +----------------+
  3. | @@tx_isolation |
  4. +----------------+
  5. | READ-COMMITTED |
  6. +----------------+
  7. 1 row in set (0.00 sec)
  8. mysql>

查询全局的事务隔离级别,可以使用

  1. mysql> select @@global.tx_isolation;
  2. +-----------------------+
  3. | @@global.tx_isolation |
  4. +-----------------------+
  5. | READ-COMMITTED        |
  6. +-----------------------+
  7. 1 row in set (0.00 sec)
  8. mysql>

在Serializable模式下。

  1. mysql> system cat /usr/local/mysql56m2/my.cnf |grep  transaction-isolation
  2. transaction-isolation = READ-COMMITTED
  3. mysql>

复制二进制与隔离级别的关系

在SERIALIZABLE模式下,Innodb存储引擎会对每个select语句自动加Lock in sharedmode,给每一个读操作加共享锁。因此在这个隔离级别下,读占用锁了,一致性的非锁定读不再予以支持。因为Innodb存储引擎在repeatable read 模式下就已经达到了3度的隔离,所以一般不在本地事务中使用serializable隔离级别,serializable的事务隔离级别主要用于innodb存储引擎的分布式事务。

在Read committed的隔离模式下,除了唯一性约束检查以及外键约束检查需要Gap lock,innodb存储引擎不会使用gap lock的锁算法。不过使用read committed隔离级别需要注意一些问题,mysql5.1中,Read committed的事务隔离级别默认只能在replication的二进制为row格式下,如果二进制默认在statement模式下,则会报如下错误:

  1. mysql> select @@version;
  2. +-------------+
  3. | @@version   |
  4. +-------------+
  5. | 5.5.25a-log |
  6. +-------------+
  7. 1 row in set (0.00 sec)
  8. mysql>
  9. mysql> select @@binlog_format;
  10. +-----------------+
  11. | @@binlog_format |
  12. +-----------------+
  13. | STATEMENT       |
  14. +-----------------+
  15. 1 row in set (0.00 sec)
  16. mysql> select @@tx_isolation;
  17. +-----------------+
  18. | @@tx_isolation  |
  19. +-----------------+
  20. | REPEATABLE-READ |
  21. +-----------------+
  22. 1 row in set (0.00 sec)
  23. mysql> set tx_isolation='READ-COMMITTED';
  24. Query OK, 0 rows affected (0.00 sec)
  25. mysql> use test;
  26. Database changed
  27. mysql> create table a (b int, primary key (b)) engine=innodb;
  28. ERROR 1050 (42S01): Table 'a' already exists
  29. mysql> select @@tx_isolation;
  30. +----------------+
  31. | @@tx_isolation |
  32. +----------------+
  33. | READ-COMMITTED |
  34. +----------------+
  35. 1 row in set (0.00 sec)
  36. mysql> begin
  37. -> ;
  38. Query OK, 0 rows affected (0.00 sec)
  39. mysql> insert into a select 100000;
  40. ERROR 1665 (HY000): Cannotexecute statement: impossible to write to binary log since BINLOG_FORMAT =STATEMENT and at least one table uses a storage engine limited to row-basedlogging. InnoDB is limited to row-logging when transaction isolation level isREAD COMMITTED or READ UNCOMMITTED.

ERROR 1665 (HY000): Cannotexecute statement: impossible to write to binary log since BINLOG_FORMAT =STATEMENT and at least one table uses a storage engine limited to row-basedlogging. InnoDB is limited to row-logging when transaction isolation level isREAD COMMITTED or READ UNCOMMITTED.

[Note]:在mysql5.1以及mysql5.6模式下实验过都是如此。也许可以知道通过将innodb_locks_unsafe_for_binlog设置为1,来可以使binlog日志在statement下使用readcommitted的事务隔离级别:

  1. mysql> select @@innodb_locks_unsafe_for_binlog;
  2. +----------------------------------+
  3. | @@innodb_locks_unsafe_for_binlog |
  4. +----------------------------------+
  5. |                               0 |
  6. +----------------------------------+
  7. 1 row in set (0.00 sec)
  8. mysql> set global innodb_locks_unsafe_for_binlog=1;
  9. ERROR 1238 (HY000): Variable 'innodb_locks_unsafe_for_binlog' is a readonly variable
  10. mysql>

此参数是只读模式,需要修改my.cnf重新启动才行。

在my.cnf里面的[mysqld]添加

[mysqld]

innodb_locks_unsafe_for_binlog = 1

然后重启,然后去check模仿一个事务操作,如下所示:

    1. mysql> select @@innodb_locks_unsafe_for_binlog;
    2. +----------------------------------+
    3. | @@innodb_locks_unsafe_for_binlog |
    4. +----------------------------------+
    5. |                               1 |
    6. +----------------------------------+
    7. 1 row in set (0.00 sec)
    8. mysql>
    9. mysql> use test;
    10. Reading table information for completion of table and column names
    11. You can turn off this feature to get a quicker startup with -A
    12. Database changed
    13. mysql> select @@tx_isolation;
    14. +----------------+
    15. | @@tx_isolation |
    16. +----------------+
    17. | READ-COMMITTED |
    18. +----------------+
    19. 1 row in set (0.00 sec)
    20. mysql> begin;
    21. Query OK, 0 rows affected (0.00 sec)
    22. mysql> insert into t select 15;
    23. Query OK, 1 row affected (0.00 sec)
    24. Records: 1  Duplicates: 0  Warnings: 0
    25. mysql> commit;
    26. Query OK, 0 rows affected (0.00 sec)
    27. mysql> select * from t;
    28. +--------+
    29. | id     |
    30. +--------+
    31. |      1 |
    32. |     12 |
    33. |     15 |
    34. |  11111 |
    35. | 111110 |
    36. +--------+
    37. 5 rows in set (0.00 sec)

[转]MySQL事务学习-->隔离级别的更多相关文章

  1. MySQL事务学习-->隔离级别

    MySQL事务学习-->隔离级别 6 事务的隔离级别 设置的目的 在数据库操作中,为了有效保证并发读取数据的正确性,提出的事务隔离级别. 数据库是要被广大客户所共享访问的,那么在数据库操作过程中 ...

  2. MySQL事务及隔离级别详解

    MySQL事务及隔离级别详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.MySQL的基本架构 MySQL的基本架构可以分为三块,即连接池,核心功能层,存储引擎层. 1> ...

  3. MySql事务及隔离级别

    在数据库中,所谓事务是指作为单个逻辑工作单元执行的一系列操作. 事务的操作: 先定义开始一个事务,然后对数据作修改操作, 这时如果提交(COMMIT),这些修改就永久地保存下来 如果回退(ROLLBA ...

  4. MySql事务的隔离级别及作用

    逻辑工作单元遵循一系列(ACID)规则则称为事务. 原子性:保证事务是一系列的运作,如果中间过程有一个不成功则全部回滚,全部成功则成功.保证了事务的原则性. 一致性:一致性指的是比如A向B转100块钱 ...

  5. MySQL事务及隔离级别(读书小结)

    标签: MySQL事务 隔离 0.什么是事务? 事务是指MySQL的一些操作看做是一个不可分割的执行单元.事务的特点是要么所有操作都执行成功,要么一个都不执行.也就是如果一个事务有操作执行失败,那么就 ...

  6. MySQL事务的隔离级别

    为什么需要隔离 当多个线程都开启事务操作数据库中的数据时,数据库系统要能进行隔离操作,以保证各个线程获取数据的准确性,在介绍数据库提供的各种隔离级别之前,我们先看看如果不考虑事务的隔离性,会发生的几种 ...

  7. mysql 事务、隔离级别

    一.事务的四大特性(ACID) 1.原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做,不可能停滞在中间环节.事务执行过程中出错,会回滚到事务开始前的状态,所有的操作就像没有 ...

  8. MySQL——事务ACID&隔离级别

    数据库事务ACID&隔离级别 什么是事务 事务是用户定义的一个数据库操作序列.这些操作要么全执行,要么全不执行,是一个不可分割的工作单元.在关系型数据库中,事务可以是一条SQL语句,也可以是一 ...

  9. MySQL 事务的隔离级别

    转载:https://developer.aliyun.com/article/743691?accounttraceid=80d4fddb3dc64b97a71118659e106221tozz 简 ...

随机推荐

  1. non linear processor

          由于自适应滤波器只能估算回音的近似值,因此它并不能将回音完全消除,也就是说,仍然有些残余的回音(Lres)留在信号当中.在任何时刻中,暂存器中的准确性正是决定残余回音音量的关键所在.如果残 ...

  2. Android中线程通信的方式

    Android 跨线程通信 android 中是不允许在主线程中进行 网络访问等事情的因为UI如果停止响应5秒左右的话整个应用就会崩溃,到Android4.0 以后 Google强制规定,与网络相关的 ...

  3. BEM

    BEM代表块(Block),元素(Element),修饰符(Modifier).BEM是由Yandex团队提出的一种CSS Class 命名方法,旨在更好的创建CSS/Sass模块.通过增加前缀的办法 ...

  4. [ 转载 ] Tcp三次握手和四次挥手详解

    #TCP的报头: 源端口号:表示发送端端口号,字段长为16位.目标端口号:表示接收端口号,字段长为16位.序列号:表示发送数据的位置,字段长为32位.每发送一次数据,就累加一次该数据字节数的大小.注意 ...

  5. ehcache 在web项目中使用

    无论是servlet web项目还是spring web项目,使用ehcache添加3个jre包以及配置 ehcache.xml即可.

  6. Codeforces Round #505 (Div 1 + Div 2) (A~D)

    目录 Codeforces 1025 A.Doggo Recoloring B.Weakened Common Divisor C.Plasticine zebra D.Recovering BST( ...

  7. hdu 5775 Bubble Sort 树状数组

    Bubble Sort 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5775 Description P is a permutation of t ...

  8. LAMP学习路线图

    站点开发概述 LAMP开发概述 HTML基础 CSS基础 DIV+CSS Javascript Jquery(Ajax) WAMP 环境搭建 PHP基本的语法,变量.数据类型,表达式,常量,流程控制, ...

  9. 坐标的相对转换ClientToScreen与ScreenToClient

    假如一个有一个TEdit的实例edt_Position,edt_Position所在容器有好几层,所在的窗体为frmMain.现要弹出一个FORM,FORM的容器为frmMain,弹出的位置在edt_ ...

  10. delphi 隐藏标题栏

      1.隐藏窗体的标题栏在Delphi中隐藏窗体的标题栏,相信大家都会说是一个件十分容易的事情,只需要设置BorderStyle的属性为bsNone就可以了,不过这种设置方法不但去掉了窗体的标题栏,而 ...