2010-05-25 22 views
7

Esta es una situación extremadamente común, por lo que estoy esperando una buena solución. Básicamente, necesitamos actualizar los contadores en nuestras tablas. A modo de ejemplo una visita la página web:Actualización de contadores a través de Hibernate

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

Así que en hibernación, tengamos este código:

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

El problema existe lee en MySQL por defecto no se presta atención a las transacciones. Por lo tanto, una página web de alto tráfico tendrá recuentos inexactos.

La manera en que yo estoy acostumbrado a hacer este tipo de cosas es simplemente llamar:

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

Creo que mi pregunta es, ¿cómo puedo hacer que en Hibernate? Y en segundo lugar, ¿cómo puedo hacer una actualización como esta en Hibernate, que es un poco más compleja?

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; 

Respuesta

5

El problema existe lee en MySQL por defecto no se presta atención a las transacciones. Por lo tanto, una página web de alto tráfico tendrá recuentos inexactos.

Indeed. Me gustaría utilizar una operación de estilo DML aquí (véase el capítulo 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(); 

que debería traducirse en

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

Y en segundo lugar, ¿cómo puedo hacer una actualización de este tipo en hibernación que es una un poco más complejo?

Hmm ... Tengo la tentación de decir "estás jodido" ... necesito pensar más sobre esto.

+0

Gracias Pascal. No sabía que podía hacer ACTUALIZACIONES dentro de HQL. Parece fácil. Pero con respecto a mi ejemplo más complejo, ¿sería víctima de la misma cuestión SELECT de no prestar atención a las transacciones? ¿Cómo sugieres que me ocupo de eso? –

0

Un stored procedure ofrece varias ventajas:

  1. En caso de que los cambios de esquema, el código no tendrá que cambiar si fuera call increment($id)
  2. problemas de concurrencia se pueden localizar.
  3. Ejecución más rápida en muchos casos.

Una posible aplicación es:

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