Estoy usando Hibernate, tratando de simular 2 actualizaciones concurrentes a la misma fila en la base de datos.hibernate Excedido el tiempo de espera de espera de bloqueo;
Editar: Moví em1.getTransaction(). Me comprometo a estar justo después de em1.flush(); No recibo ninguna StaleObjectException, las dos transacciones se han confirmado correctamente.
Session em1=Manager.sessionFactory.openSession();
Session em2=Manager.sessionFactory.openSession();
em1.getTransaction().begin();
em2.getTransaction().begin();
UserAccount c1 = (UserAccount)em1.get(UserAccount.class, "root");
UserAccount c2 = (UserAccount)em2.get(UserAccount.class, "root");
c1.setBalance(c1.getBalance() -1);
em1.flush();
System.out.println("balance1 is "+c2.getBalance());
c2.setBalance(c2.getBalance() -1);
em2.flush(); // fail
em1.getTransaction().commit();
em2.getTransaction().commit();
System.out.println("balance2 is "+c2.getBalance());
obteniendo la siguiente excepción en em2.flush()
. ¿Por qué?
2009-12-23 21:48:37,648 WARN JDBCExceptionReporter:100 - SQL Error: 1205, SQLState: 41000
2009-12-23 21:48:37,649 ERROR JDBCExceptionReporter:101 - Lock wait timeout exceeded; try restarting transaction
2009-12-23 21:48:37,650 ERROR AbstractFlushingEventListener:324 - Could not synchronize database state with session
org.hibernate.exception.GenericJDBCException: Could not execute JDBC batch update
at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:126)
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:114)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:275)
at org.hibernate.persister.entity.AbstractEntityPersister.processGeneratedProperties(AbstractEntityPersister.java:3702)
at org.hibernate.persister.entity.AbstractEntityPersister.processUpdateGeneratedProperties(AbstractEntityPersister.java:3691)
at org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:147)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:279)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:263)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:168)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1028)
at com.ch.whoisserver.test.StressTest.main(StressTest.java:54)
Caused by: java.sql.BatchUpdateException: Lock wait timeout exceeded; try restarting transaction
at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:1213)
at com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:912)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268)
... 10 more
Estoy tratando de escribir un caso de prueba para ver si funciona el bloqueo optimista, el objeto UserCuenta en cuestión está utilizando la versión, consulte esta pregunta para obtener más información http://stackoverflow.com/questions/1938671/concurrency- in-hibernate, en este caso con dos hilos ¿transacción2 obtendría staledObjectException para detectar un cambio en los datos subyacentes? – user217631
@unknown Sí, lo haría. – KLE
He actualizado mi respuesta anterior: usar dos hilos no es una buena manera de probar ** específicamente ** bloqueo optimista (debido a ser impredecible) – ChssPly76