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項目,利用悲觀所解決併發問題是不合理的,因爲你無法保證一個常連接。
發佈了14 篇原創文章 · 獲贊 0 · 訪問量 3649
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章