[英]hibernate Lock wait timeout exceeded;
I am using Hibernate, trying to simulate 2 concurrent update to the same row in database. 我正在使用Hibernate,试图模拟2个并发更新到数据库中的同一行。
Edit: I moved em1.getTransaction().commit to be right after em1.flush(); 编辑:我移动em1.getTransaction()。提交在em1.flush()之后; I am not getting any StaleObjectException, the two transactions committed successfully.
我没有得到任何StaleObjectException,这两个事务成功提交。
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());
I getting the following exception on em2.flush()
. 我在
em2.flush()
上得到以下异常。 Why? 为什么?
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
Well, you're trying to get into a deadlock and you're succeeding :-) 好吧,你正试图陷入僵局并且你取得了成功:-)
Real life simulation would have 1st and 2nd entity manager plus appropriate updates / transactions in separate threads. 真实生活模拟将在第一个和第二个实体管理器以及单独线程中的适当更新/事务。 That way you'd have:
那样你就有:
Note that at that point (#4 above) you'd be overwriting changes made by Transaction1. 请注意,在那时(上面的#4),您将覆盖Transaction1所做的更改。 Hibernate can use optimistic locking as well as pessimistic locking to prevent that from happening.
Hibernate可以使用乐观锁定和悲观锁定来防止这种情况发生。
Update (based on comment): 更新 (根据评论):
If the entity is versioned, Transaction2 (#4 above) will fail. 如果实体是版本化的,则Transaction2(上面的#4)将失败。 However, your code as posted does not get to that point because Transaction2 can't obtain the lock as explained above.
但是,您发布的代码没有到达那一点,因为Transaction2无法获得锁定,如上所述。 If you want to specifically test that optimistic version control is working you can do the following:
如果您想要专门测试乐观版本控件是否正常工作,您可以执行以下操作:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.