2010-05-25 53 views
7

這是一種非常常見的情況,所以我期待着一個好的解決方案。基本上我們需要更新我們表格中的計數器。作爲一個例子網頁,請訪問:通過休眠更新計數器

Web_Page 
-------- 
Id 
Url 
Visit_Count 

所以在Hibernate中,我們可能有這樣的代碼:

webPage.setVisitCount(webPage.getVisitCount()+1); 

的問題有在MySQL默認讀取不注意的交易。所以一個高度被販運的網頁會有不準確的數字。

我已經習慣了做這種類型的事情的方式是直接電話諮詢:

update Web_Page set Visit_Count=Visit_Count+1 where Id=12345; 

我想我的問題是,我該怎麼做,在休眠?其次,我如何在Hibernate中做這樣的更新,這有點複雜?

update Web_Page wp set wp.Visit_Count=(select stats.Visits from Statistics stats where stats.Web_Page_Id=wp.Id) + 1 where Id=12345; 

回答

5

問題有默認在MySQL讀不注重交易。所以一個高度被販運的網頁會有不準確的數字。

確實。我想在這裏使用一個DML操作風格(見13.4. DML-style operations):

Session session = sessionFactory.openSession(); 
Transaction tx = session.beginTransaction(); 

String hqlUpdate = "update webPage wp set wp.visitCount = wp.visitCount + 1 where wp.id = :id"; 
int updatedEntities = s.createQuery(hqlUpdate) 
     .setLong("newName", 1234l) 
     .executeUpdate(); 
tx.commit(); 
session.close(); 

應導致

update Web_Page set Visit_Count=Visit_Count+1 where Id=12345; 

其次哪個,我怎麼可以這樣做的更新在Hibernate中這是一個有點複雜?

嗯......我很想說「你搞砸了......」需要更多地思考這個問題。

+0

謝謝帕斯卡爾。我不知道我可以在HQL中做更新。看起來很容易。但是就我的更復雜的例子而言,它會成爲不關注交易的SELECT問題的受害者嗎?你如何建議我處理? – 2010-05-25 22:16:34

0

一個stored procedure有幾個好處:

  1. 萬一架構更改,代碼不需要改變,如果它是call increment($id)
  2. 併發問題可以本地化。
  3. 在很多情況下執行速度更快。

一種可能的實現是:

create procedure increment (IN id integer) 
begin 
    update web_page 
     set visit_count = visit_count + 1 
     where `id` = id; 
end