2012-09-09 108 views
0

我有以下的,每次我想要做一些動作與休眠我的應用程序代碼:如何使用Hibernate正確

Session session = HibernateUtil.getSessionFactory().openSession(); 
session.beginTransaction(); 
session.save(obj); //or delete, update etc. 
session.getTransaction().commit(); 
session.close(); 

這當然不是一個好的做法。訪問hibernate的最佳方式是什麼,而不是像這樣的情況?我應該使用一些包含靜態方法的'Util'類來完成相同的工作嗎?也許單身人士更好?我還需要在線程或SwingWorker中封裝這些代碼,以便在訪問數據庫時不凍結我的GUI。

+5

爲什麼這不是一個好習慣? –

+3

通常我使用彈簧聲明式事務管理功能來實現這一點。它有助於保持代碼清潔並專注於您的業務邏輯。看看[Spring AOP Tx管理](http://www.mkyong.com/spring/spring-aop-transaction-management-in-hibernate/) – zoidbeck

回答

0

是的,該代碼是非常糟糕的。

  1. 它爲每個數據庫訪問打開一個事務。這是低效的,而且很可能不正確(通常的動作的整組必須是原子的。比如考慮

    public void buy(String accountId) { 
        Account account = load(accountId); 
        account.balance -= 100; 
        save(account); 
    } 
    

    如果加載和保存在自己的交易,以及一些邪惡的用戶同時購買2項時,可能出現以下情況:

    • 線程1讀取餘額(= 1000)
    • 線程2讀取餘額(= 1000)
    • 線程1將結餘(= 900)
    • 線程2將結餘(= 900)

    ,使用戶買了兩次,但只支付一次;-)

  2. 如果保存未完成的交易()拋出異常。事實上,本次交易將繼續開放下去,包括所有其持有的鎖...

複雜性等,這些都是大多數人劃分事務的聲明的原因,而不是重新方形輪,例如與SpringEJB

0

我認爲解決是如果通過了應用程序所需要這個功能,那麼它可能是明智的,在服務方面,各地編寫基於帳戶ID

@Service 
public class AccountService { 
    private Map<String, ReentrantLock> locks = new HashMap<Long, ReentrantLock>(); 

    private void unlock(String id) { 
     ReentrantLock lock = locks.get(id); 
     if (lock != null && lock.isLocked()) { 
      lock.unlock(); 
     } 
    } 

    private void lock(String id) { 
     ReentrantLock lock; 
     synchronized (locks) { 
      lock = locks.get(id); 
      if (lock == null) { 
       lock = new ReentrantLock(); 
       locks.put(id, lock); 
      } 
     } 
     lock.lock(); 
    } 

public void buy(String accountId) { 
    this.lock(accountId); 
    try{ 
     Account account = load(accountId); 
     account.balance -= 100; 
     save(account); 
    }finally{ 
     this.unlock(accountId); 
    } 
    } 
} 

收購renentranlock。

+0

我認爲更多的解釋會對你有所幫助 – Atul

0

我強烈建議閱讀Hibernate網站上的this文章。

本文對於任何想在Hibernate中使用會話和事務的最佳方式的人來說都是必須的。

基本上最好的設計模式,將取決於

由於已經由梅里,開啓和關閉指出你 所選擇的事務管理策略(JDBC,JTA),並申請交易(編程/聲明)的模式你的代碼中每個方法的事務(假設有幾個這樣的方法按順序工作以形成一個原子操作)是一個反模式。這也在文章中更詳細地討論。