hibernate锁实验,以及解决方案

	Object lock = new Object();
	
	private void transactionCollision() throws InterruptedException {
		Session session = HibernateSessionFactory.getSession();
		User ben = (User)session.get(User.class, new Long(1));
		new BranchThread().start();
		synchronized (lock) {//Before being notify the obj would be locked.
			lock.wait();
		}
		session.beginTransaction();
		ben.setNickName(ben.getNickName() + "do sth_a");
		session.getTransaction().commit();
		session.close();
	}

	private class BranchThread implements Runnable {

		public void run() {
			synchronized (lock) {
				try {
					lock.wait(2*1000);//wait 2 seconds the ensure
					// the main thread would read the dirt data.
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				lock.notifyAll();
				Session session = HibernateSessionFactory.getSession();
				User ben = (User) session.get(User.class, new Long(1));
				session.beginTransaction();
				ben.setNickName(ben.getNickName() + "do sth_b");
				session.getTransaction().commit();
				session.close();
			}
		}

		public void start() {
			new Thread(this).start();
		}

	}

典型的更新丢失问题,当然这是利用synchronized模拟的极端情况,但极端情况并不代表不发生。解决方案之一是加入乐观锁。具体操作过程如下:
entity加入一个数字类型属性,该属性与业务逻辑无关,被hibernate用作版本戳,具体如下:
	private Integer version = new Integer(0);

重新配置hbm.xml文件,将该字段应慎到数据库中
<id name="oid" type="long">
			<generator class="native" />
		</id>
		<version name="version" type="int" />

配置之后在执行上述语句会抛出:org.hibernate.StaleObjectStateException
参考文章:
http://www.360doc.com/showWeb/0/0/415808.aspx
http://www.360doc.com/showWeb/0/0/415808.aspx

以上属于乐观锁解决方案,还可以考虑悲观所解决方案;但悲观所解决方案需要一个与数据库的常链接,所以我认为,作为b/s项目,利用悲观所解决并发问题是不合理的,因为你无法保证一个常连接。

你可能感兴趣的:(thread,Hibernate,xml)