攻城狮在路上(壹) Hibernate(十七)--- Hibernate并发处理问题
一、多个事务并发运行时的并发问题:
总结为第一类丢失更新、脏读、虚读、不可重复读、第二类丢失更新。
1、第一类丢失更新: 撤销一个事务时,把其他事务已提交的更新数据覆盖。
2、脏读: 一个事务读到另一个事务未提交的更新数据。
3、虚读(幻读): 一个事务读到另一个事务已提交的新插入的数据。
4、不可重复读: 一个事务读到另一个事务已提交的更新数据。
5、第二类丢失更新: 这是不可重复读的特例,一个事务覆盖另一个事务已提交的更新数据。
二、数据库系统的锁的基本原理:
数据库系统采用锁来实现事务的隔离性。
1、锁的基本原理如下:
A、当一个事务访问某种数据库资源时,如果执行select语句,必须先获得共享锁;如果执行insert、update或者delete语句,必须获得独占锁。
B、当第二个事务也要访问相同的资源时,如果执行select语句,也必须先获得共享锁;如果执行inert、update或者delete语句,也必须先获得独占锁。此时根据已经放置在资源上的锁的类型,来决定第二个事务应该等待还是立即获取该锁。
第二个事务获取锁的情况说明:
| 资源上已经放置的锁 | 第二个事务进行读操作 | 第二个事务进行更新操作 |
| 无 | 立即获得共享锁 | 立即获得独占锁 |
| 共享锁 | 立即获得共享锁 | 等待第一个事务解除共享锁 |
| 独占锁 | 等待第一个事务解除独占锁 | 等待第一个事务解除独占锁 |
2、锁的多粒度性及自动锁升级:
数据库系统能够锁定的资源包括:数据库、表、区域、页面、键值(指带有索引的行数据)、行。
按照锁定资源的粒度,锁可以分为以下类型:
A、数据库级锁:锁定整个数据库。
B、表级锁:锁定一张数据库表。
C、区域级锁:锁定数据库的特定区域。
D、页面级锁:锁定数据库的特定页面。
E、键值级锁:锁定数据库表中带有索引的一行记录。
F、行级锁:锁定数据库表中的单行记录。
锁的粒度越大,事务间的隔离性就越高,事务间的并发性能就越低。
锁升级是指调整锁的粒度,将多个低粒度的锁替换成少数更高粒度的锁,以此来降低系统负荷。
3、锁的类型和兼容性:
A、共享锁:
共享锁用于读数据操作,它是非独占的,允许其他事务同时读取其锁定的资源,但是不允许其他事务更新它。
B、独占锁:
独占锁也叫排他锁,适用于修改数据的场合。它所锁定的资源,其他事务不能读取也不能修改。
C、更新锁:
更新锁在更新操作的初始化阶段用来锁定可能要被修改的资源,这样可以避免使用共享锁造成的死锁现象。
共享锁、独占锁、更新锁的特征总结:
| 特征项 | 共享锁 | 独占锁 | 更新锁 |
| 加锁条件 | 当一个事务执行select语句时,数据库会为这个事务分配一个共享锁,来锁定被查询的数据。 | 事务执行inert、update、delete语句时,分配独占锁。 | 事务执行update语句时,分配更新锁 |
| 解锁条件 | 一般数据被读取后,数据库系统立刻解除共享锁。当查询多条记录时,也是一条一条的锁定-解锁。 | 独占锁直到事务结束才能被解除。 | 数据读取完毕,执行更新操作时,会把更新锁升级为独占锁。 |
| 与其他锁兼容性 | 如果数据资源上放置了共享锁,还能再放置共享锁和更新锁。 | 不能和其他锁兼容。 | 与共享锁兼容,但只能有一个更新锁,这样可以避免死锁 |
| 并发性能 | 具有良好的并发性能 | 并发性能较差 |
4、死锁及其防治方法:
在数据库系统中,死锁是指多个事务分别锁定一个资源,又试图请求锁定对方已经锁定的资源,这就产生了一个锁定请求环,导致多个事务都处于等待对方释放锁定资源的状态。
许多数据库系统能自动定期搜索和处理死锁问题,当检测到锁定请求环时,系统将结束死锁优先级最低的事务,并撤销该事务。
避免死锁的方法:
A、合理安排表访问顺序。
B、使用短事务。
C、如果对数据的一致性要求不是很高,可以允许脏读。
D、如果可能的话,错开多个事务访问相同数据资源的时间,以防止锁冲突。
E、使用尽可能低的事务隔离级别。
三、数据库的隔离级别:
一般情况下,应首先考虑让数据库系统自动管理锁。
数据库提供了4种事务隔离级别供用户选择:
| 隔离级别 | 是否有第一类丢失更新 | 是否脏读 | 是否虚读 | 是否不可重复读 | 是否第二类丢失更新 |
| Serializable | 否 | 否 | 否 | 否 | 否 |
| Repeatable Read | 否 | 否 | 是 | 否 | 否 |
| Read Commited | 否 | 否 | 是 | 是 | 是 |
| Read Uncommited | 否 | 是 | 是 | 是 | 是 |
1、在mysql.exe中设置隔离级别的相关语句:
select @@tx_isolation;
set transaction isolation level read commited;
set global transaction isolation level read commited;
2、在应用程序中设置隔离级别:
在Hibernate配置文件中可一个显式配置:
hibernate.connection.isolation=2
1:Read Uncommited; 2:Read Commited; 4:Repeatable Read; 8:Serializabel
四、在应用程序中使用悲观锁:
1、从应用程序的角度,锁可以分为2类:
A、悲观锁:指在应用程序中显式的为数据资源加锁。会影响并发性能。
B、乐观锁:乐观锁假定当前事务操作数据资源时,不会有其他事务同时访问该数据资源,因此完全依靠数据库的隔离级别来自动管理锁。
2、悲观锁的实现方式:
A、在应用程序中显示指定采用数据库系统的独占锁来锁定数据源。
B、通过在数据库表中增加一个标记字段,来判断事务是否可以访问。
3、利用数据库系统的独占锁来实现悲观锁:
A、SQL语句控制:
select .. for update;
B、Hibernate中使用get()或者load()方法时:
Account account = (Account)session.get(Account.class,new Long(1),LockMode.UPGRADE);
LockMode不再深入介绍。
五、利用Hibernate的版本控制来实现乐观锁:
基本的实现逻辑是:在数据库里定义一个表示版本的字段,或者一个时间戳字段,然后在映射文件中配置一个<version>元素,或者一个<timestamp>元素。
暂时不做深入了解。
攻城狮在路上(壹) Hibernate(十七)--- Hibernate并发处理问题的更多相关文章
- 攻城狮在路上(壹) Hibernate(十八)--- 管理Hibernate的缓存
一般Session的缓存被称为Hibernate的第一级缓存,SessionFactory的外置缓存是一个可配置的缓存插件,称为Hibernate的第二级缓存.一.缓存的基本原理: 1.持久化层的缓存 ...
- 攻城狮在路上(壹) Hibernate(二)--- 第一个hibernate程序
1.直接通过JDBC API持久化实体域对象: A.java.sql常用接口和类: DriverManager:驱动程序管理器,负责创建数据库连接. Connection:代表数据库连接. State ...
- 攻城狮在路上(壹) Hibernate(十六)--- Hibernate声明数据库事务
一.数据库事务的概念: 数据库的ACID特征:Atomic.Consistency.Isolation.Durability.原子性.一致性.隔离性.持久性.不同的隔离级别引发的不同问题. 事务的AC ...
- 攻城狮在路上(壹) Hibernate(十五)--- Hibernate的高级配置
一.配置数据库连接池: 1.使用默认的数据库连接池: Hibernate提供了默认了数据库连接池,它的实现类为DriverManegerConnectionProvider,如果在Hibernate的 ...
- 攻城狮在路上(壹) Hibernate(十四)--- Hibernate的检索方式(下)
本节介绍HQL和QBC的高级用法:各种连接查询.投影查询.报表查询.动态查询.集合过滤和子查询等.另外将归纳优化查询程序代码,从而提高查询性能的各种技巧.一.连接查询: HQL与QBC支持的各种连接类 ...
- 攻城狮在路上(壹) Hibernate(十三)--- Hibernate的检索方式(上)
Hibernate提供了以下几种检索对象的方式: A.导航对象图检索方式. B.OID检索方式.Session.get() load(); C.HQL检索方式.Query. D.QBC检索方式.Que ...
- 攻城狮在路上(壹) Hibernate(十二)--- Hibernate的检索策略
本文依旧以Customer类和Order类进行说明.一.引言: Hibernate检索Customer对象时立即检索与之关联的Order对象,这种检索策略为立即检索策略.立即检索策略存在两大不足: A ...
- 攻城狮在路上(壹) Hibernate(十)--- 映射值类型集合
一.映射Set(集):未排序,无重复. 实例代码: <set name="images" table="IMAGES" lazy="true&q ...
- 攻城狮在路上(壹) Hibernate(九)--- Hibernate的映射类型
Hibernate采用映射类型作为Java类型和SQL类型的桥梁,对应type属性.分为两种:内置映射类型和客户化映射类型.一.内置映射类型: 1.Java基本类型的Hibernate映射类型: Ja ...
随机推荐
- django缓存
由于Django是动态网站,所有每次请求均会去数据进行相应的操作,当程序访问量大时,耗时必然会更加明显,最简单解决方式是使用:缓存,缓存将一个某个views的返回值保存至内存或者memcache中,5 ...
- Node.js简介
Node核心思想:1.非阻塞:2.单线程:3.事件驱动. 在目前的web应用中,客户端和服务器端之间有些交互可以认为是基于事件的,那么AJAX就是页面及时响应的关键.每次发送一个请求时(不管请求的数据 ...
- jq隐藏页面的一行
<script type="text/javascript" src="http://files.cnblogs.com/914556495wxkj/jquery- ...
- 【leetcode】Symmetric Tree
Symmetric Tree Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its ...
- C#之设置无边框后如何移动窗体(转)
转载:http://www.cnblogs.com/techmango/archive/2012/03/31/2427523.html 第一种,利用windows的消息机制来实现: 首先﹐.定义鼠標左 ...
- 利用ssh-copy-id无需密码登录远程服务器
本地机器生成公钥和私钥 ssh-keygen -t rsa 一路回车,最后会在~/.ssh目录下生成id_rsa和id_rsa.pub这两个文件. 与远程服务器建立信任机制 ssh-copy-id - ...
- (转载)使用 udev 高效、动态地管理 Linux 设备文件
概述: Linux 用户常常会很难鉴别同一类型的设备名,比如 eth0, eth1, sda, sdb 等等.通过观察这些设备的内核设备名称,用户通常能知道这些是什么类型的设备,但是不知道哪一个设备是 ...
- Application.AddMessageFilter(this);
开发环境:windows 8(x64), vs2013 只要“项目属性-调试”中选中“启用Visual Studio承载进程“,在VS2013中用F5调试,调用Application.AddMessa ...
- FFmpeg-20160415-snapshot-bin
ESC 退出 0 进度条开关 1 屏幕原始大小 2 屏幕1/2大小 3 屏幕1/3大小 4 屏幕1/4大小 S 下一帧 [ -2秒 ] +2秒 ; -1秒 ' +1秒 下一个帧 -> -5秒 F ...
- 上传文件报错System.Net.ProtocolViolationException: 必须先将 ContentLength 字节写入请求流,然后再调用 [Begin]GetResponse。
在上传文件的时候报错. 错误: System.Net.ProtocolViolationException: 必须先将 ContentLength 字节写入请求流,然后再调用 [Begin]GetRe ...