一.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. matlab 排列组合

    0. gamma 函数与阶乘 gamma(n+1) == n! == prod(1:n); gammaln():gamma 函数的返回值,gammaln(A) = log(gamma(A)), 之所以 ...

  2. python 教程 第六章、 模块

    第六章. 模块 1) 模块 sys模块 字节编译的.pyc文件,优化编译后生成pyo文件 2) from..import语句 import sys print 'The command line ar ...

  3. .net core config读取

    最简单的方式 引用 Microsoft.Extensions.Configuration Microsoft.Extensions.Configuration.Json json文件 新建一个Conf ...

  4. WPF中ItemsControl应用虚拟化时找到子元素的方法

    原文:WPF中ItemsControl应用虚拟化时找到子元素的方法  wpf的虚拟化技术会使UI的控件只初始化看的到的子元素, 而不是所有子元素都被初始化,这样会提高UI性能. 但是我们经常会遇到一个 ...

  5. 【C#】获取任意文件的缩略图

    原文:[C#]获取任意文件的缩略图 因为用shell取缩略图时,对于损坏的文件,读出来的图有黑边,所以就诞生了以下方法,不过这个效率要比用shell取的低3-4倍. 1.添加类WindowsThumb ...

  6. 给Delphi程序添加版本信息(EXE和Dll)

    我们在用Delphi编译完程序,准备发布产品时,总希望随产品发布个性信息以标示产品的来源以及开发者等信息,就像windows的程序一样,使我们一看属性就知道他是微软的产品,这些在Delphi中是如何实 ...

  7. 使用BGP的虚拟下一跳实现IGP的路由负载

    网络拓扑: XRV1 ============================================================== !hostname XRV1! interface ...

  8. Windows 10开发基础——XML和JSON (一)

    主要内容: JSON的序列化与反序列化 XML的序列化与反序列化 1.JSON的序列化与反序列化     JSON(JavaScript Object Notation)是一种轻量级的数据交换语言,它 ...

  9. windows 2003 无法安装 .net4.0 windows服务

    错误: InstallUtil.InstallLog文件中的错误信息:   正在运行事务处理安装.   正在开始安装的“安装”阶段. 查看日志文件的内容以获得 D:\Debug\DataChang.e ...

  10. Delphi7 时钟(使用了多个自定义组件)

    http://download.csdn.net/detail/akof1314/3073289