[转]MySQL事务学习-->隔离级别
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命令重置
- mysql> set global tx_isolation='REPEATABLE-READ';
- Query OK, 0 rows affected (0.01 sec)
- mysql>
查询当前的会话事务级别,可以使用:
- mysql> select @@tx_isolation;
- +----------------+
- | @@tx_isolation |
- +----------------+
- | READ-COMMITTED |
- +----------------+
- 1 row in set (0.00 sec)
- mysql>
查询全局的事务隔离级别,可以使用
- mysql> select @@global.tx_isolation;
- +-----------------------+
- | @@global.tx_isolation |
- +-----------------------+
- | READ-COMMITTED |
- +-----------------------+
- 1 row in set (0.00 sec)
- mysql>
在Serializable模式下。
- mysql> system cat /usr/local/mysql56m2/my.cnf |grep transaction-isolation
- transaction-isolation = READ-COMMITTED
- 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模式下,则会报如下错误:
- mysql> select @@version;
- +-------------+
- | @@version |
- +-------------+
- | 5.5.25a-log |
- +-------------+
- 1 row in set (0.00 sec)
- mysql>
- mysql> select @@binlog_format;
- +-----------------+
- | @@binlog_format |
- +-----------------+
- | STATEMENT |
- +-----------------+
- 1 row in set (0.00 sec)
- mysql> select @@tx_isolation;
- +-----------------+
- | @@tx_isolation |
- +-----------------+
- | REPEATABLE-READ |
- +-----------------+
- 1 row in set (0.00 sec)
- mysql> set tx_isolation='READ-COMMITTED';
- Query OK, 0 rows affected (0.00 sec)
- mysql> use test;
- Database changed
- mysql> create table a (b int, primary key (b)) engine=innodb;
- ERROR 1050 (42S01): Table 'a' already exists
- mysql> select @@tx_isolation;
- +----------------+
- | @@tx_isolation |
- +----------------+
- | READ-COMMITTED |
- +----------------+
- 1 row in set (0.00 sec)
- mysql> begin
- -> ;
- Query OK, 0 rows affected (0.00 sec)
- mysql> insert into a select 100000;
- 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的事务隔离级别:
- mysql> select @@innodb_locks_unsafe_for_binlog;
- +----------------------------------+
- | @@innodb_locks_unsafe_for_binlog |
- +----------------------------------+
- | 0 |
- +----------------------------------+
- 1 row in set (0.00 sec)
- mysql> set global innodb_locks_unsafe_for_binlog=1;
- ERROR 1238 (HY000): Variable 'innodb_locks_unsafe_for_binlog' is a readonly variable
- mysql>
此参数是只读模式,需要修改my.cnf重新启动才行。
在my.cnf里面的[mysqld]添加
[mysqld]
innodb_locks_unsafe_for_binlog = 1
然后重启,然后去check模仿一个事务操作,如下所示:
- mysql> select @@innodb_locks_unsafe_for_binlog;
- +----------------------------------+
- | @@innodb_locks_unsafe_for_binlog |
- +----------------------------------+
- | 1 |
- +----------------------------------+
- 1 row in set (0.00 sec)
- mysql>
- mysql> use test;
- Reading table information for completion of table and column names
- You can turn off this feature to get a quicker startup with -A
- Database changed
- mysql> select @@tx_isolation;
- +----------------+
- | @@tx_isolation |
- +----------------+
- | READ-COMMITTED |
- +----------------+
- 1 row in set (0.00 sec)
- mysql> begin;
- Query OK, 0 rows affected (0.00 sec)
- mysql> insert into t select 15;
- Query OK, 1 row affected (0.00 sec)
- Records: 1 Duplicates: 0 Warnings: 0
- mysql> commit;
- Query OK, 0 rows affected (0.00 sec)
- mysql> select * from t;
- +--------+
- | id |
- +--------+
- | 1 |
- | 12 |
- | 15 |
- | 11111 |
- | 111110 |
- +--------+
- 5 rows in set (0.00 sec)
[转]MySQL事务学习-->隔离级别的更多相关文章
- MySQL事务学习-->隔离级别
MySQL事务学习-->隔离级别 6 事务的隔离级别 设置的目的 在数据库操作中,为了有效保证并发读取数据的正确性,提出的事务隔离级别. 数据库是要被广大客户所共享访问的,那么在数据库操作过程中 ...
- MySQL事务及隔离级别详解
MySQL事务及隔离级别详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.MySQL的基本架构 MySQL的基本架构可以分为三块,即连接池,核心功能层,存储引擎层. 1> ...
- MySql事务及隔离级别
在数据库中,所谓事务是指作为单个逻辑工作单元执行的一系列操作. 事务的操作: 先定义开始一个事务,然后对数据作修改操作, 这时如果提交(COMMIT),这些修改就永久地保存下来 如果回退(ROLLBA ...
- MySql事务的隔离级别及作用
逻辑工作单元遵循一系列(ACID)规则则称为事务. 原子性:保证事务是一系列的运作,如果中间过程有一个不成功则全部回滚,全部成功则成功.保证了事务的原则性. 一致性:一致性指的是比如A向B转100块钱 ...
- MySQL事务及隔离级别(读书小结)
标签: MySQL事务 隔离 0.什么是事务? 事务是指MySQL的一些操作看做是一个不可分割的执行单元.事务的特点是要么所有操作都执行成功,要么一个都不执行.也就是如果一个事务有操作执行失败,那么就 ...
- MySQL事务的隔离级别
为什么需要隔离 当多个线程都开启事务操作数据库中的数据时,数据库系统要能进行隔离操作,以保证各个线程获取数据的准确性,在介绍数据库提供的各种隔离级别之前,我们先看看如果不考虑事务的隔离性,会发生的几种 ...
- mysql 事务、隔离级别
一.事务的四大特性(ACID) 1.原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做,不可能停滞在中间环节.事务执行过程中出错,会回滚到事务开始前的状态,所有的操作就像没有 ...
- MySQL——事务ACID&隔离级别
数据库事务ACID&隔离级别 什么是事务 事务是用户定义的一个数据库操作序列.这些操作要么全执行,要么全不执行,是一个不可分割的工作单元.在关系型数据库中,事务可以是一条SQL语句,也可以是一 ...
- MySQL 事务的隔离级别
转载:https://developer.aliyun.com/article/743691?accounttraceid=80d4fddb3dc64b97a71118659e106221tozz 简 ...
随机推荐
- Channel Allocation HDU1373
染色问题:相邻不能染同一种颜色 最少需要的颜色的数量=最大团点的数量 #include<bits/stdc++.h> using namespace std; #define N 27 i ...
- 002.etcd使用场景
引用链接: https://blog.csdn.net/linuxheik/article/details/77853119 https://www.cnblogs.com/doscho/p/6221 ...
- 大数据技术之_16_Scala学习_01_Scala 语言概述
第一章 Scala 语言概述1.1 why is Scala 语言?1.2 Scala 语言诞生小故事1.3 Scala 和 Java 以及 jvm 的关系分析图1.4 Scala 语言的特点1.5 ...
- 跟厂长学PHP7内核(八):深入理解字符串的实现
在前面大致预览了常用变量的结构之后,我们今天来仔细的剖析一下字符串的具体实现. 一.字符串的结构 struct _zend_string { zend_refcounted_h gc; /* 字符串类 ...
- Oracle的一些初步小东西
经常要用数据库,让他自己启动的话,开机太慢,所以用命令启动方便点. 1.开启: 在运行中输入cmd,进入控制台,lsnrctl start回车,提示启动监听成功后net start Oracl ...
- hdu 3360 最小点覆盖 **
题意:给你一个图,图中有宝物和保安两种元素.每个宝物需要周围的某些位置同时安放保安(如果那些位置有宝物,可以把宝物替换成保安)问你最少需要再安置多少保安,可以使所有宝物满足要求. 题意有点难懂 链接: ...
- BZOJ1768 : [Ceoi2009]logs
从上到下枚举行,可以$O(m)$更新现在每一列往上连续的1的个数,也可以在$O(m)$的时间内完成排序.总复杂度$O(nm)$. #include<cstdio> #define M 15 ...
- [Java]进程与线程的区别(转)
线程是指进程内的一个执行单元,也是进程内的可调度实体. 与进程的区别: (1)地址空间:进程内的一个执行单元;进程至少有一个线程;它们共享进程的地址空间;而进程有自己独立的地址空间; (2)资源拥有: ...
- USB2.0 速度识别--区分低速-高速-全速
USB2.0是向下兼容USB1.X的,即USB2.0支持高速,全速,低速的USB设备 (HIGH-SPEED,FULL-SPEED,LOW-SPEED),而USB1.X不支持高速设备. 因此如果高速设 ...
- [Go] 命令行参数解析包(flag 包)使用详解
Go 的 flag 包可以解析命令行的参数. 一.命令行语法 命令行语法主要有以下几种形式: cmd -flag // 只支持bool类型 cmd -flag=xxx cmd -flag ...