一.Spring支持四种事务隔离级别:

1.ISOLATION_READ_UNCOMMITTED(读未提交):这是事务最低的隔离级别,它充许令外一个事务可以看到这个事务未提交的数据。

2.ISOLATION_READ_COMMITTED(读已提交): 保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据

3.ISOLATION_REPEATABLE_READ(可重复读): 这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻像读。

4.ISOLATION_SERIALIZABLE(可串行化) 这是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。

spring设置中还有一个默认级别:

ISOLATION_DEFAULT:使用数据库默认的事务隔离级别。

二、一些名词

多个事务并发会产生一些问题:

脏读:可以读取到其他事务修改但未提交的脏数据。

不可重复读:在一个事务中重复读取相同数据。在其中两次读取数据之间有另一个事务修改并提交了该数据。使得事务两次读到的数据是不一样的。

幻读: 第一个事务对一个表中的数据进行了修改,这种修改涉及 到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有 修改的数据行,就好象发生了幻觉一样。

丢失更新: 多个用户同时对一个数据资源进行更新,必定会产生被覆盖的数据,造成数据读写异常。

例子:假定有数据表

==student==

id | name

1  | 张三

a.脏读

事务A:select name from student where id=1;

事务B:update  student set name='李四' where id=1;不提交

结果:可能是“李四”

读已提交:避免读取未提交数据。

b.不可重复读

事务A:select name from student where id=1;

      select name from student where id=1;

事务B:update  student set name='李四' where id=1;提交

结果:第一次读到“张三”,第二次可能读到“李四”

可重复读:避免事务B修改id为1的数据。但是事务B可以向表中新增数据李四

c.幻读

事务A:select name from student;

      select name from student;

事务B:insert into student values(default,'李四');提交

结果:第一次读到“张三”,第二次可能读到"张三"和"李四"

串行化读:每次读都需要获得表级共享锁,读写相互都会阻塞。可避免幻读。

各种隔离级别与各种读的关系:

三、MySQL默认隔离级别

MySQL/InnoDB默认是可重复读的(REPEATABLE READ);

Oracle默认隔离级别是读已提交(READ_COMMITTED);

四、修改与查询MySQL事务隔离级别的方法:

 #查全局事务隔离级别
SELECT @@global.tx_isolation;
#查当前会话事务隔离级别
SELECT @@session.tx_isolation;
#查当前事务隔离级别
SELECT @@tx_isolation;
#设置全局隔离级别
set global transaction isolation level read committed;
#设置当前会话隔离级别
set session transaction isolation level read committed;

其它隔离级别的设置就不说了。

测试,以root身份登陆,修改session.tx_isolation:

退出mysql,再次以root身份登陆,上次会话的设置失效:

更换身份,使用foreigner身份登陆,修改全局权限:

再次以root身份登陆,查看权限:

可见,全局事务隔离级别是MySQL全局的,与某个用户的或者某个会话的隔离级别没有关系。

 五、锁机制

定义:当有事务操作时,数据库引擎会要求不同类型的锁定,如相关数据行、数据页或是整个数据表,当锁定运行时,会阻止其他事务对已经锁定的数据行、数据页或数据表进行操作。只有在当前事务对于自己锁定的资源不在需要时,才会释放其锁定的资源,供其他事务使用。

我个人对锁的理解是,某线程想要执行某个事务中的某条sql,必须得有某个锁。如果没有该锁,要等待自己获得该锁后才能执行相应操作。

共享锁(Share)

共享锁的代号是S,共享锁的锁粒度是行或者元组(多个行)。一个事务获取了共享锁之后,可以对锁定范围内的数据执行读操作。

排它锁(eXclusive)

排它锁的代号是X,是eXclusive的缩写,排它锁的粒度与共享锁相同,也是行或者元组。一个事务获取了排它锁之后,可以对锁定范围内的数据执行写操作。

意向锁

意向锁的含义是如果对一个结点加意向锁,则说明该结点的下层结点正在被加锁;对任一结点加锁时,必须先对它的上层结点加意向锁。如:对表中的任一行加锁时,必须先对它所在的表加意向锁,然后再对该行加锁。这样一来,事务对表加锁时,就不再需要检查表中每行记录的锁标志位了,系统效率得以大大提高。

简单的说就是我要对哪个表进行事务操作了,就给哪个表加一个意向锁。

锁的互斥与兼容关系

锁和锁之间的关系,要么是相容的,要么是互斥的。

锁a和锁b相容是指:操作同样一组数据时,如果事务t1获取了锁a,另一个事务t2还可以获取锁b;

锁a和锁b互斥是指:操作同样一组数据时,如果事务t1获取了锁a,另一个事务t2在t1释放锁a之前无法获取锁b。

上面提到的共享锁、排它锁、意向共享锁、意向排它锁相互之前都是有兼容/互斥关系的,可以用一个兼容性矩阵表示(y表示相容,n表示互斥):

六、悲观锁和乐观锁

悲观锁(Pessimistic Lock), 每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。

乐观锁(Optimistic Lock), 每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库如果提供类似于write_condition机制的其实都是提供的乐观锁。

两种锁各有优缺点,不可认为一种好于另一种,像乐观锁适用于写比较少的情况下,即冲突真的很少发生的时候,这样可以省去了锁的开销,加大了系统的整个吞吐量。但如果经常产生冲突,上层应用会不断的进行retry,这样反倒是降低了性能,所以这种情况下用悲观锁就比较合适。

七、丢失更新及解决方法。

丢失更新:

假设没有X锁存在。执行A,B两个事务。下面这种情况事务A的提交会被事务B的提交覆盖

解决办法,加入X锁即可。

Mysql事务隔离级别和锁机制的更多相关文章

  1. 详解Mysql事务隔离级别与锁机制

    一.概述 我们的数据库一般都会并发执行多个事务,多个事务可能会并发的对相同的一批数据进行增删改查操作,可能 就会导致我们说的脏写. 胀读和不可重复读.幻读这些问题. 这些问题的本质都是数据库的多事务并 ...

  2. MySQL事务隔离级别,锁(转)

    add by zhj: 本文针对的是MySQL的InnoDB存储引擎,不适用于MySQL的其它存储引擎和其它数据库 原文:MySQL数据库事务隔离级别(Transaction Isolation Le ...

  3. mysql事务隔离级别及传播机制

    TRANSACTION(事务隔离级别) 在说明事务隔离级别之前先说一下脏读.不可重复读.幻读这三个概念. 脏读:一个事务读取到另一事务未提交的更新新据.当一个事务正在访问数据,并且对数据进行了修改,而 ...

  4. SqlServer中的事务隔离级别、锁机制

    事务 作用:用来执行一连串的动作,并且保证所有动作要么都执行.要么都不执行. 属性:原子行.一致性.隔离性.持久性 锁 作用:SqlServer使用锁来实施事务隔离属性. 阻塞 定义:如果一个事务持有 ...

  5. mysql事务隔离级别详解和实战

    A事务做了操作 没有提交 对B事务来说 就等于没做 获取的都是之前的数据 但是 在A事务中查询的话 查到的都是操作之后的数据 没有提交的数据只有自己看得到,并没有update到数据库. 查看InnoD ...

  6. autocommit 隔离级别 next lock gap lock 事务隔离级别和锁

    autocommit 隔离级别 https://www.ibm.com/developerworks/cn/opensource/os-mysql-transaction-isolation-leve ...

  7. MySQL数据库引擎、事务隔离级别、锁

    MySQL数据库引擎.事务隔离级别.锁 数据库引擎InnoDB和MyISAM有什么区别 大体区别为: MyISAM类型不支持事务处理等高级处理,而InnoDB类型支持.MyISAM类型的表强调的是性能 ...

  8. 重新学习MySQL数据库9:Innodb中的事务隔离级别和锁的关系

    重新学习MySQL数据库9:Innodb中的事务隔离级别和锁的关系 Innodb中的事务隔离级别和锁的关系 前言: 我们都知道事务的几种性质,数据库为了维护这些性质,尤其是一致性和隔离性,一般使用加锁 ...

  9. 一文读懂MySQL的事务隔离级别及MVCC机制

    回顾前文: 一文学会MySQL的explain工具 一文读懂MySQL的索引结构及查询优化 (同时再次强调,这几篇关于MySQL的探究都是基于5.7版本,相关总结与结论不一定适用于其他版本) 就软件开 ...

随机推荐

  1. P和P1指向了O和O1两个变量(对象)的地址, 而不是O和O1的内容(对象的实际地址)——充分证明@是取变量(对象)的地址,而不是变量里面的内容,够清楚!

    如图,为什么这样取出来的p,p1的值不一样呢?   165232328群友庾伟洪告诉我:  P和P1指向了O和O1两个变量(对象)的地址, 而不是O和O1的内容(对象的实际地址) ,你想P指向真正的对 ...

  2. 绝对和相对误差(absolute & relative error)

    1. 标量 真实值为 x,测量值为 x0, 绝对误差(absolute error):Δx=x0−x(有单位): 相对误差(relative error):δx=Δxx=x0−xx=x0x−1(是一个 ...

  3. 用 theano 求解 Logistic Regression (SGD 优化算法)

    1. model 这里待求解的是一个 binary logistic regression,它是一个分类模型,参数是权值矩阵 W 和偏置向量 b.该模型所要估计的是概率 P(Y=1|x),简记为 p, ...

  4. Qt使用预编译头文件Using Precompiled Headers(提升10倍以上)

    预编译头文件是被很多编译器用来编译稳定的代码以及将编译好的稳定代码存储在二进制文件中用于提升编译性能.在随后的编译中,编译器将加载存储状态继续编译指定的文件.每一个随后的编译将更快,因为稳定的代码不需 ...

  5. swagger ui 值类型形参加文字注释

    例: @ApiImplicitParams({ @ApiImplicitParam(paramType = "query", name = "indexCondition ...

  6. 《C++ Primer Plus》学习笔记11

    <C++ Primer Plus>学习笔记11 第17章 输入.输出和文件 <<<<<<<<<<<<<< ...

  7. 用树莓派和DS18B20做个汽车温度记录仪

    原文:用树莓派和DS18B20做个汽车温度记录仪 用树莓派和DS18B20做个汽车温度记录仪[原创] 很想知道夏日阳光暴晒下,汽车内的最高温度以及温度的变化情况.觉得用树莓派和DS18B20来实现应该 ...

  8. WPF值转换器的使用

    <Window x:Class="CollectionBinding.MainWindow"        xmlns="http://schemas.micros ...

  9. C# TCP 通讯

    //接收 using System; using System.Collections.Generic;using System.ComponentModel;using System.Data;us ...

  10. 深入理解Delphi的消息机制(别人写的,简明扼要,用来复习)

    永远记住,无论你是用 SDK 还是借用 VCL 来创建窗口,都要遵循 Windows 的游戏规则,即先注册窗口类,然后再创建窗口实例,在消息循环中写实现代码.你还要知道 Windows 已经为了我们预 ...