`

二十 悲观锁和乐观锁

 
阅读更多
为了避免对对象同步操作时候产生的数据不一致问题,我们对对象采用加锁机制

悲观锁:从读取的时候开始加锁,直到修改完成。

缺点:读取完以后,用户修改过程缓慢,造成同步性降低。

乐观锁:给每条记录添加版本号,用来区别。两人同时编辑时候,假设获取的版本号都为1,编辑完提交的时候,版本号为2,
第一个提交完以后,数据库版本号为2,第二个提交的时候对比版本号就会报错。
解决的方法:在实体中加上版本号属性 在该映射文件中利用version节点配置其版本号,这样就可以由hibernate自己去维护
实体 部门
package vo.util.bean;

import java.util.Set;

/**
 * 部门类
 * @author Administrator
 *
 */
public class Department {
  private int id;
  private String name;
  private Set<Employee> ems;
  //版本号
  private int v;

public int getV() {
	return v;
}
public void setV(int v) {
	this.v = v;
}
public int getId() {
	return id;
}
public Set<Employee> getEms() {
	return ems;
}
public void setEms(Set<Employee> ems) {
	this.ems = ems;
}
public void setId(int id) {
	this.id = id;
}
public String getName() {
	return name;
}
public void setName(String name) {
	this.name = name;
}
}

映射文件
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping 
	package="vo.util.bean">

	<class name="Department">
		<id name="id">
			<generator class="native"/>
		</id>
		<!-- 配置版本号  必须在id的下面来定义-->
		<version name="v"/>
		<property name="name"/>
		
		<!-- 配置一对多的映射关系  -->
		<set name="ems">
		<!-- 关联关系的外键  -->
		<key column="depaer_id"/>
		   <!-- 关联关系的实体类配置 -->
		  <one-to-many  class="Employee" />
		</set>
	</class>
	
</hibernate-mapping>




测试
package vo.util.test;

import java.util.HashSet;
import java.util.Set;

import org.hibernate.Session;
import org.hibernate.Transaction;

import vo.util.HibernateUtil;
import vo.util.bean.Department;
import vo.util.bean.Employee;

public class VersonTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
	add();
	update(1);
	}
   
	static void update(int id)
	{   
		Session s1=null;
		Transaction tx1=null;
		Session s2=null;
		try {
			Transaction tx2 = null;
			s1 = HibernateUtil.getSession();
			tx1 = s1.beginTransaction();
			Department d1 = (Department) s1.get(Department.class, id);
			
			s2 = HibernateUtil.getSession();
			tx2 = s2.beginTransaction();
			Department d2 = (Department) s2.get(Department.class, id);
			d1.setName("new1");
			d2.setName("new2");
			tx2.commit();
			tx1.commit();
		   } finally {
			 s1.close();   
	         s2.close();
		   }
			   
	    }   

	
	
	 static Department add(){
	    	Session session = null;
	    	Transaction tx = null;
	    	try{
	    		session =HibernateUtil.getSession();
	    		tx = session.beginTransaction();
	    		//…你的代码save,delete,update,get…
	    		Department dpart=new Department();
	    		dpart.setName("政企事业部");
	    		//dpart.setVar(1);
	    		
	    		Employee em1=new Employee();
	    		em1.setName("员工李小仙");
	    		//em1.setDerpartment(dpart);
	    		
	    		Employee em2=new Employee();
	    		em2.setName("员工张小三");
	    		//em2.setDerpartment(dpart);
	    		
	    		Set<Employee> em=new HashSet<Employee>();
	    	    em.add(em1);
	    	    em.add(em2);
	    	    
	    	    dpart.setEms(em);
	    		session.save(dpart);
	    		session.save(em1);
	    		session.save(em2);
	    		
	    		
	    		tx.commit();
	    		return dpart;
	    	}finally{
	    		if(session != null)session.close();
	    	} 

	    }
}



运行测试
log4j:WARN No appenders could be found for logger (org.hibernate.cfg.Environment).
log4j:WARN Please initialize the log4j system properly.
打开连接成功!Hibernate: insert into Department (v, name) values (?, ?)
Hibernate: insert into Employee (name, depaer_id) values (?, ?)
Hibernate: insert into Employee (name, depaer_id) values (?, ?)
Hibernate: update Employee set depaer_id=? where id=?
Hibernate: update Employee set depaer_id=? where id=?
Hibernate: select department0_.id as id0_0_, department0_.v as v0_0_, department0_.name as name0_0_ from Department department0_ where department0_.id=?
Hibernate: select department0_.id as id0_0_, department0_.v as v0_0_, department0_.name as name0_0_ from Department department0_ where department0_.id=?
Hibernate: update Department set v=?, name=? where id=? and v=?
Hibernate: update Department set v=?, name=? where id=? and v=?
Exception in thread "main" org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [vo.util.bean.Department#1]
	at org.hibernate.persister.entity.AbstractEntityPersister.check(AbstractEntityPersister.java:1765)
	at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2407)
	at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:2307)
	at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2607)
	at org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:92)
	at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:250)
	at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:234)
	at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:142)
	at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
	at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
	at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
	at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
	at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
	at vo.util.test.VersonTest.update(VersonTest.java:41)
	at vo.util.test.VersonTest.main(VersonTest.java:21)


分析:第一次更新语句下没报异常,第二次更新就报异常了,这是因为版本号不一致,已经修改了的问题 这是不
是解决了同步修改的问题呢?



完毕 end!

 

分享到:
评论

相关推荐

    thinkPHP框架乐观锁和悲观锁实例分析

    在ThinkPHP框架中,常见的有乐观锁和悲观锁两种机制。本文将通过实例分析这两种锁在ThinkPHP框架中的应用,以及它们各自的优缺点。 首先,让我们从乐观锁开始了解。乐观锁机制假设多个事务在处理数据时很少发生冲突...

    数据库事务、hibernate悲观锁和乐观锁

    在处理并发问题时,Hibernate提供了悲观锁和乐观锁两种机制。 悲观锁假设并发环境中的冲突是常态,因此在读取数据时就立即锁定,直到事务结束才释放。在Hibernate中,可以通过设置`@LockModeType.PESSIMISTIC_READ`...

    Hibernate悲观锁和乐观锁的实现

    悲观锁和乐观锁是两种常见的锁定策略,它们各有特点,适用于不同的场景。 **悲观锁**(Pessimistic Lock)的名字来源于其悲观的态度,它认为数据随时可能被其他事务修改,因此在读取数据时就立即进行加锁,防止其他...

    Java 中的悲观锁和乐观锁的实现

    悲观锁和乐观锁各有优缺点,选择哪种锁机制取决于具体的应用场景和需求。悲观锁适合数据修改频繁且对数据一致性要求较高的场景;而乐观锁适用于数据修改较少且并发量较大的场景。在实际应用中,可以根据具体情况灵活...

    乐观锁与悲观锁

    介绍数据库事务的定义和事务带来的问题,详细讲解乐观锁与悲观锁的区别

    并发控制—悲观锁和乐观锁

    并发控制—悲观锁和乐观锁

    Hibernate锁机制_悲观锁和乐观锁

    Hibernate 锁机制_悲观锁和乐观锁 Hibernate 锁机制是指在数据库访问中,为了维护数据的一致性和正确性,所采取的一些机制来防止数据的并发访问和修改。 Hibernate 中有两种锁机制:悲观锁和乐观锁。 一、悲观锁...

    面试必备之乐观锁与悲观锁.pdf

    悲观锁和乐观锁是计算机科学中用于处理并发控制的两种不同策略,它们主要应用于多线程环境下数据的一致性和完整性保护。两种锁的设计哲学反映了对数据并发访问时的不同预期。 **悲观锁**: - **定义**:悲观锁是一...

    Hibernate的乐观锁与悲观锁

    **Hibernate**作为一种流行的Java持久层框架,提供了多种机制来处理并发控制问题,其中最常用的就是**乐观锁**和**悲观锁**。本文将详细介绍这两种锁的原理、应用场景以及如何在Hibernate中实现。 #### 二、悲观锁...

    Hibernate乐观锁和悲观锁分析

    主要分为两种类型:乐观锁(Optimistic Locking)和悲观锁(Pessimistic Locking)。 **悲观锁(Pessimistic Locking)** 悲观锁假设数据在任何时候都可能发生并发冲突,因此在数据读取时就对其进行锁定,确保在...

    Hibernate悲观锁与乐观锁案例

    在Java的持久化框架Hibernate中,悲观锁和乐观锁是两种重要的并发控制策略,它们用于管理数据库中的数据在多线程环境下的访问安全。本文将深入探讨这两种锁机制的原理、应用场景及其区别。 首先,我们来理解悲观锁...

    悲观锁和乐观锁的技术对比和应用.docx

    悲观锁和乐观锁是两种常见的并发控制策略,用于在多任务环境下确保数据一致性。它们各自有不同的工作原理和适用场景。 悲观锁(Pessimistic Lock)正如其名,它假设并发环境中会发生频繁的冲突,因此在读取数据时就...

    十三、关于悲观锁和乐观锁.xmind

    十三、关于悲观锁和乐观锁

    悲观锁和乐观锁.md

    所谓乐观锁,重视假设最好的情况,每次去拿数据都认为别人不会修改,所以不会上锁,但是会在更新时判断一下在此期间这个数据有没有更改,使用版本号机制和CAS算法实现,乐观锁适用于多读的应用类型,这样可以提高...

    Hibernate悲观锁与乐观锁

    Hibernate,作为一款流行的Java持久化框架,提供了两种主要的锁定策略:悲观锁和乐观锁,以应对不同场景下的并发控制需求。 悲观锁,正如其名,它对并发访问持悲观态度,预设在读取数据时,可能存在其他用户同时...

    hibernate乐观锁和悲观锁学习

    本文主要讨论的是Hibernate框架中两种锁机制的使用:乐观锁和悲观锁。 首先,让我们深入理解悲观锁(Pessimistic Locking)。悲观锁正如其名字所示,假设并发环境中数据会被频繁修改,所以在整个数据处理过程中,它...

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

    Hibernate 实现悲观锁和乐观锁代码介绍 Hibernate 是一个基于 Java 的持久层框架,它提供了多种锁机制来实现事务的隔离性和一致性。在本文中,我们将详细介绍 Hibernate 实现悲观锁和乐观锁的代码实现,并讨论 ...

Global site tag (gtag.js) - Google Analytics