Hibernate征途(八)之锁
来源:互联网 发布:mysql触发器的触发语句 编辑:程序博客网 时间:2024/04/29 15:07
锁是在开发中常见的一个问题,锁住的数据可以保证访问的排他性,可以说只要当同一个资源有可能被同时访问时,就应当考虑到锁的问题。Hibernate中锁有两种:悲观锁和乐观锁。
悲观锁
悲观锁的意思是,对数据访问、修改可能出现的问题持悲观的态度,所以要防范于最初的未然:在数据的整个访问过程中都将数据锁定。悲观锁的实现,依靠数据库提供的锁机制,因为在数据一旦被访问就被锁定,所以可以保证实现真正的访问排他性,否则,即使在本系统中实现了加锁机制,也无法保证外部系统不会修改数据。
最常见的方式为:
select * from t_Student where name='tgb' for update在Hibernate中,我们可以使用的方式为:
Inventory实体类
public class Inventory {private String itemNo;private String itemName;private int quantity; //省略getter和setter……}测试
public void testLoad1(){Session session=null;try {session=HibernateUtils.getSession();session.getTransaction().begin();Inventory inventory =(Inventory)session.load(Inventory.class, "10001", LockMode.UPGRADE);System.out.println("user1——itemNo: "+inventory.getItemNo());System.out.println("user1——itemName: "+inventory.getItemName());System.out.println("user1——quantity: "+inventory.getQuantity());inventory.setQuantity(inventory.getQuantity()-200);session.getTransaction().commit();} catch (Exception e) {session.getTransaction().rollback();e.printStackTrace();}finally{HibernateUtils.closeSession(session);}}文中,LockMode.UPGRADE 的意思是利用数据库的 for update 子句加锁。在System.out.println("user1——quantity: "+inventory.getQuantity());行加断点,可以看到发出的语句为:
Hibernate: select inventory0_.itemNo as itemNo0_0_, inventory0_.itemName as itemName0_0_, inventory0_.quantity as quantity0_0_ from t_inventory inventory0_ where inventory0_.itemNo=? for updateuser1——itemNo: 10001user1——itemName: 神农三鹿user1——quantity: 1000在事务提交前,其它程序是无法访问此条数据的。悲观锁大多数情况下依靠数据库的锁机制实现,以保证操作最大程度的独占性。但这会增大数据库性能的大量开销,特别对长事务而言,这样的开销会非常高。
乐观锁
与悲观相对,乐观锁是更宽松的加锁机制,对数据的访问、修改持乐观的态度:程序们想怎么改就怎么改吧,能保证数据访问不冲突、没有脏数据就好……乐观锁的实现靠的是对版本号的控制,一般为表增加一个版本version字段,判断程序中跟随数据读出来的版本号是否小于数据库中保存的版本号,如果小于则不可以修改数据,否则可以修改。Hibernate中的乐观锁的实现,需要映射文件的属性修改。
映射文件
<hibernate-mapping ><class name="com.tgb.hibernate.Inventory" table="t_inventory" optimistic-lock="version"><id name="itemNo"><generator class="assigned" /></id><property name="itemName" /><property name="quantity"/><property name="version"/></class></hibernate-mapping>测试
public void testLoad1(){Session session=null;try {session=HibernateUtils.getSession();session.getTransaction().begin();Inventory inventory =(Inventory)session.load(Inventory.class, "10001", LockMode.UPGRADE);System.out.println("user1——itemNo: "+inventory.getItemNo());System.out.println("user1——itemName: "+inventory.getItemName());System.out.println("user1——quantity: "+inventory.getQuantity());inventory.setQuantity(inventory.getQuantity()-200);session.getTransaction().commit();} catch (Exception e) {session.getTransaction().rollback();e.printStackTrace();}finally{HibernateUtils.closeSession(session);}}此时,保持此测试程序对数据的加锁,先使用其他测试程序对此数据修改后,再执行此测试程序会发生错误:
乐观锁机制避免了长事务中的数据库加锁开销,大大提升了大并发量下的系统整体性能表现;但因为乐观锁机制往往与系统的数据存储逻辑有关系,例如其他系统对数据的同时修改,可能会将脏数据存入数据库。
总结
二者的使用要根据实际情况,悲观锁和乐观锁就先说到这里。
- Hibernate征途(八)之锁
- Hibernate征途(一)之初识
- Hibernate征途(四)之映射 序
- Hibernate征途(三)之CRUD
- Hibernate征途(二)之基础与核心
- Hibernate征途(六)之数量和关系映射
- Hibernate征途(五)之继承映射和组件映射
- Hibernate征途(七)之复合主键映射和集合映射
- (八)Hibernate之JAP使用
- 我的见解之hibernate(八)
- Hibernate教程之八二级缓存
- Hibernate (八)二级缓存
- 千山万水之Hibernate(八)——继承映射
- Hibernate的学习之路八(持久化类)
- 征途
- 【Hibernate框架开发之八】Hibernate 查询语言Query Language(HQL)
- 精通Hibernate之映射继承关系八
- 深入研究Hibernate之八:一对一
- 斗地主算法的设计与实现(六)--项目源码和说明
- 【一天一篇CPP】多态性和虚函数和虚析构函数和纯虚函数和抽象类
- 2013.10.10(天津站)百度研发一面试总结
- 用两个栈实现一个队列——我作为面试官的小结
- android特效集锦系列之九 仿网易新闻图片切换
- Hibernate征途(八)之锁
- Java类加载原理解析
- 关于 python ImportError: No module named 的问题
- 2013年-校招常见的笔试题
- setsockopt()用法(参数详细说明)
- android特效集锦系列之十 仿新浪微博TabHost菜单
- framework中写个java文件,读取手机底层文件数据,提供接口,返回值给上层应用
- 保存yum下载的rpm包
- AS3 TimerManager