Hibernate实现悲观锁和乐观锁代码介绍

四种隔离机制不要忘记:(1,2,4,8)

1.read-uncommitted:能够去读那些没有提交的数据(允许脏读的存在)

2.read-committed:不会出现脏读,因为只有另一个事务提交才会读取来结果,但仍然会出现不可重复读和幻读现象。

4.repeatable read: MySQL 默认。可重复读,读数据读出来之后给它加把锁,其他人先别更新,等我用完了你再更新。你的事务没完,其他事务就不可能改这条记录。

8.serializable:序列化,最高级别。一个一个来,不去并发。效率最低。

hibernate的隔离机制

i.hibernate.connection.isolation=2

ii.用悲观锁解决:repeatable read的问题(依赖于数据库的锁)

a)LockMode.None 无锁的机制,Transaction结束时,切换到此模式

b)LockMode.read 在查询的时候 hibernate会自动获取锁

c)LockMode.write insert update hibernate会自动获取锁

d)以上3中锁的模式,是hibernate内部使用的

e)LockMode.UPGRADE_NOWAIT ORACLE支持的锁的方式

例子:

Account.java:

package com.bjsxt.hibernate;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class Account {
private int id;
private int balance; //BigDecimal
@Id
@GeneratedValue
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getBalance() {
return balance;
}
public void setBalance(int balance) {
this.balance = balance;
}
} 

hibernate.cfg.xml中配置:

<mapping class="com.bjsxt.hibernate.Account"/> 

测试:

@Test
public void testSave() {
Session session = sf.openSession();
session.beginTransaction();
Account a = new Account();
a.setBalance(100);
session.save(a);
session.getTransaction().commit();
session.close();
}
@Test
public void testOperation1() {
Session session = sf.openSession();
session.beginTransaction();
Account a = (Account)session.load(Account.class, 1);
int balance = a.getBalance();
//do some caculations
balance = balance - 10;
//在保存时很有可能会把在同一时期修改的给覆盖掉
//这个时候上一把"锁"就可以避免这个问题
a.setBalance(balance);
session.getTransaction().commit();
session.close();
}
//下面这个就是对上面那个例子做的修改
@Test
public void testPessimisticLock() {
Session session = sf.openSession();
session.beginTransaction();
//给它加把锁,加锁的机制上面已经提到了
Account a = (Account)session.load(Account.class, 1, LockMode.UPGRADE);
int balance = a.getBalance();
//do some caculation
balance = balance - 10;
a.setBalance(balance);
session.getTransaction().commit();
session.close();
} 

这是依赖于数据库的锁的,也就是给数据库一个指令,要求数据库帮忙加锁。
——————————————————————————————————————

iii.Hibernate(JPA)乐观锁定(ReadCommitted)

这不是依赖数据库加锁的,是在程序中加锁的。

举个例子:一个数据需要隔离机制(不能重复读),这个时候在更新的字段上加"版本号"(version字段),一旦有人给它update一下,这个值就加1(version+1)。

那么这种机制是如何产生隔离能力的呢?

原因是事务A读取字段的同时,事务B紧接着也读取这个字段,而且改了它,此时version变成1了。这个时候事务A就会检查字段是否被改变了,如果被改变它也做相应的改变,没有改变就不改。

乐观锁的实现:(@Version)

Account.java:

package com.bjsxt.hibernate;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Version;
@Entity
public class Account {
private int id;
private int balance;
private int version;
@Version//加了这个注解就说明这个是专门用来做版本标注的
public int getVersion() {
return version;
}
public void setVersion(int version) {
this.version = version;
}
@Id
@GeneratedValue
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getBalance() {
return balance;
}
public void setBalance(int balance) {
this.balance = balance;
}
} 

测试:

 @Test
public void testSave() {
Session session = sf.openSession();
session.beginTransaction();
Account a = new Account();
a.setBalance(100);
session.save(a);
session.getTransaction().commit();
session.close();
}
@Test
public void testOptimisticLock() {
Session session = sf.openSession();
Session session2 = sf.openSession();
session.beginTransaction();
Account a1 = (Account) session.load(Account.class, 1);
session2.beginTransaction();
Account a2 = (Account) session2.load(Account.class, 1);
a1.setBalance(900);
a2.setBalance(1100);
//第一个session一旦提交,version就会+1
session.getTransaction().commit();
System.out.println(a1.getVersion());
//第二个session提交的时候,一看version不一样就会报错
//出了错误做个记录,下次再提交(也可以用其他方法)
        session2.getTransaction().commit();
System.out.println(a2.getVersion());
session.close();
session2.close();
} 

悲观乐观的区别:悲观锁认为一定会受到影响,我加锁谁也别想动。
乐观锁,没出事就好,出了事我再想办法解决。

总结

以上就是本文关于Hibernate实现悲观锁和乐观锁代码介绍的全部内容,希望对大家学习hibernate有所帮助。有什么问题可以随时留言,小编会及时回复大家。感谢大家对本站的支持。

(0)

相关推荐

  • 详解JAVAEE——SSH三大框架整合(spring+struts2+hibernate)

    一.整合原理 二.导包(41个) 1.hibernate (1)hibernate/lib/required (2)hibernate/lib/jpa | java persist api java的持久化规范(接口) (3)数据库驱动 2.struts2 (1)struts-blank.war/WEB-INF/lib/* 注意:javassist-3.18.1-GA.jar包与hibernate中的重复(只保留高版本即可) (2)struts整合spring插件包 注意:这个包一旦导入,那么s

  • 分布式Hibernate search详解

    分布式Hibernate Search与Apache Tomcat6,ActiveMQ 和Spring.今天我将跟大家分享我的经验,以master/slave(s)方式配置分布式Hibernate Search并整合Apache ActiveMQ,Spring,应用程序额容器是Apache Tomcat 6. 怎么工作: -Hibernate Search 支持使用JMS back-end 和 master/slave(s) 索引进行分布式配置 - mater通过网络共享暴露索引 (例如通过NF

  • Hibernate5新特性介绍

    在hibernate5中,有了一些新的变动: 新引导 API Spatial/GIS 支持 Java 8 支持 扩展 AUTO id 生成支持 命名策略分离 属性转换器支持 更好的 "bulk id table" 支持 事务管理 模式工具链 Session API类化 改进 OSGi 支持 改进 bytecode 增强功能 新的引导API 用来引导Hibernate(建立一个SessionFactory)的经典方式一直都是利用Configuration配置类.从

  • Hibernate实现悲观锁和乐观锁代码介绍

    四种隔离机制不要忘记:(1,2,4,8) 1.read-uncommitted:能够去读那些没有提交的数据(允许脏读的存在) 2.read-committed:不会出现脏读,因为只有另一个事务提交才会读取来结果,但仍然会出现不可重复读和幻读现象. 4.repeatable read: MySQL 默认.可重复读,读数据读出来之后给它加把锁,其他人先别更新,等我用完了你再更新.你的事务没完,其他事务就不可能改这条记录. 8.serializable:序列化,最高级别.一个一个来,不去并发.效率最低

  • Hibernate悲观锁和乐观锁实例详解

    本文研究的主要是Hibernate悲观锁和乐观锁的全部内容,具体介绍如下. 悲观锁 悲观锁通常是由数据库机制实现的,在整个过程中把数据锁住(查询时),只要事物不释放(提交/回滚),那么任何用户都不能查看或修改. 下面我们通过一个案例来说明. 案例:假设货物库存为1000,当核算员1取出了数据准备修改,但临时有事,就走了.期间核算员2取出了数据把数量减去200,然后核算员1回来了把刚才取出的数量减去200,这就出现了一个问题,核算员1并没有在800的基础上做修改.这就是所谓的更新丢失,采用悲观锁可

  • Java中数据库常用的两把锁之乐观锁和悲观锁

    在写入数据库的时候需要有锁,比如同时写入数据库的时候会出现丢数据,那么就需要锁机制. 数据锁分为乐观锁和悲观锁,那么它们使用的场景如下: 1. 乐观锁适用于写少读多的情景,因为这种乐观锁相当于JAVA的CAS,所以多条数据同时过来的时候,不用等待,可以立即进行返回. 2. 悲观锁适用于写多读少的情景,这种情况也相当于JAVA的synchronized,reentrantLock等,大量数据过来的时候,只有一条数据可以被写入,其他的数据需要等待.执行完成后下一条数据可以继续. 他们实现的方式上有所

  • 详解Java中的悲观锁与乐观锁

    一.悲观锁 悲观锁顾名思义是从悲观的角度去思考问题,解决问题.它总是会假设当前情况是最坏的情况,在每次去拿数据的时候,都会认为数据会被别人改变,因此在每次进行拿数据操作的时候都会加锁,如此一来,如果此时有别人也来拿这个数据的时候就会阻塞知道它拿到锁.在Java中,Synchronized和ReentrantLock等独占锁的实现机制就是基于悲观锁思想.在数据库中也经常用到这种锁机制,如行锁,表锁,读写锁等,都是在操作之前先上锁,保证共享资源只能给一个操作(一个线程)使用. 由于悲观锁的频繁加锁,

  • MySQL悲观锁与乐观锁的实现方案

    目录 前言 实战 1.无锁 2.悲观锁 3.乐观锁 总结 前言 悲观锁和乐观锁是用来解决并发问题的两种思想,在不同的平台有着各自的实现.例如在Java中,synchronized就可以认为是悲观锁的实现(不严谨,有锁升级的过程,升级到重量级锁才算),Atomic***原子类可以认为是乐观锁的实现. 悲观锁 具有强烈的独占和排他特性,在整个处理过程中将数据处于锁定状态,一般是通过系统的互斥量来实现.当其他线程想要获取锁时会被阻塞,直到持有锁的线程释放锁. 乐观锁 对数据的修改和访问持乐观态度,假设

  • Mysql中悲观锁与乐观锁应用介绍

    目录 1.锁 2.悲观锁 3.乐观锁 4.如何选择 1.锁 ​ 生活中:锁在我们身边无处不在,比如我出门玩去了需要把门锁上,比如我需要把钱放到保险柜里面,必须上锁以保证我财产的安全. 代码中:比如多个线程需要同时操作修改共享变量,这时需要给变量上把锁(syncronized),保证变量值是对的. 数据库表:当多个用户修改表中同一数据时,我们可以给该行数据上锁(行锁). sql脚本 CREATE TABLE `sys_user` ( `id` bigint(20) NOT NULL COMMENT

  • Mysql悲观锁和乐观锁的使用示例

    悲观锁 悲观锁,认为数据是悲观的.当我们查询数据的时候加上锁.防止其他线程篡改,直到对方拿到锁,才能修改. 比如,有如下的表.status=1表示可以下单,status=2表示不可以下订单.假如在并发的过程中有两个用户同时查到status=1,那么从逻辑上来说都可以去新增订单,但是会造成商品超卖. 如下例子 CREATE TABLE `goods` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) DEFAULT NULL,

  • mysql 悲观锁与乐观锁的理解及应用分析

    本文实例讲述了mysql 悲观锁与乐观锁.分享给大家供大家参考,具体如下: 悲观锁与乐观锁是人们定义出来的概念,你可以理解为一种思想,是处理并发资源的常用手段. 不要把他们与mysql中提供的锁机制(表锁,行锁,排他锁,共享锁)混为一谈. 一.悲观锁 顾名思义,就是对于数据的处理持悲观态度,总认为会发生并发冲突,获取和修改数据时,别人会修改数据.所以在整个数据处理过程中,需要将数据锁定. 悲观锁的实现,通常依靠数据库提供的锁机制实现,比如mysql的排他锁,select .... for upd

  • Java中的悲观锁与乐观锁是什么

    乐观锁对应于生活中乐观的人总是想着事情往好的方向发展,悲观锁对应于生活中悲观的人总是想着事情往坏的方向发展.这两种人各有优缺点,不能不以场景而定说一种人好于另外一种人. 悲观锁 总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁(共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程).传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁.Java中sy

  • MySQL中的悲观锁与乐观锁

    在关系型数据库中,悲观锁与乐观锁是解决资源并发场景的解决方案,接下来将详细讲解

随机推荐