二十 悲观锁和乐观锁

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

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

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

乐观锁:给每条记录添加版本号,用来区别。两人同时编辑时候,假设获取的版本号都为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!

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值