2010-05-25 47 views
7

Dies ist eine sehr häufige Situation, so erwarte ich eine gute Lösung. Grundsätzlich müssen wir die Zähler in unseren Tabellen aktualisieren. Als Beispiel einer Webseite besuchen:Aktualisieren von Zählern durch Hibernate

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

So in Hibernate, könnten wir diesen Code haben:

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

Das Problem dort liest in MySQL ist standardmäßig nicht aufpasst auf Transaktionen. Eine Website mit hohem Trafficking weist daher ungenaue Zählungen auf.

Die Art, wie ich zu tun, diese Art der Sache bin es gewöhnt ist einfach anrufen:

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

Ich denke, meine Frage ist, wie mache ich das in den Ruhezustand? Und zweitens, wie kann ich ein solches Update in Hibernate machen, das ein bisschen komplexer ist?

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; 

Antwort

5

Das Problem gibt es standardmäßig in mysql liest zahlen keine Aufmerksamkeit auf Transaktionen. Eine Website mit hohem Trafficking weist daher ungenaue Zählungen auf.

In der Tat. Ich würde hier einen DML-Stil Betrieb verwenden (siehe Kapitel 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(); 

die in

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

Und zweitens führen soll, wie kann ich ein Update, wie dies in dem Ruhezustand zu tun, das ist ein etwas komplexer?

Hmm ... Ich bin versucht zu sagen "du bist verschraubt" ... musst mehr darüber nachdenken.

+0

Danke Pascal. Ich wusste nicht, dass ich UPDATE innerhalb von HQL machen könnte. Sieht einfach aus. Aber würde das, was mein komplexeres Beispiel betrifft, demselben SELECT-Problem zum Opfer fallen, wenn ich Transaktionen nicht beachten würde? Wie schlägst du vor, dass ich damit umgehe? –

0

A stored procedure bietet mehrere Vorteile:

  1. Falls die Schemaänderungen müssen nicht den Code ändern, wenn es call increment($id) waren
  2. Concurrency Probleme lokalisiert werden können.
  3. Schnellere Ausführung in vielen Fällen.

Eine mögliche Implementierung ist:

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