简体   繁体   English

hibernate锁定等待超时超时;

[英]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 :-) 好吧,你正试图陷入僵局并且你取得了成功:-)

  1. Transaction1 starts, updates (and locks) row with your entity. Transaction1启动,更新(和锁定)您实体的行。
  2. Transaction2 tries to do the same but can't because the row is still locked. Transaction2尝试执行相同操作但不能,因为该行仍处于锁定状态。 So it waits (and waits, and waits) until timeout is exceeded 所以它等待(并等待,等待),直到超过超时

Real life simulation would have 1st and 2nd entity manager plus appropriate updates / transactions in separate threads. 真实生活模拟将在第一个和第二个实体管理器以及单独线程中的适当更新/事务。 That way you'd have: 那样你就有:

  1. Transaction1 starts, updates (and locks) row with your entity. Transaction1启动,更新(和锁定)您实体的行。
  2. Transaction2 tries to do the same but can't because the row is still locked. Transaction2尝试执行相同操作但不能,因为该行仍处于锁定状态。 So it waits (and waits, and waits) ... 所以它等待(等待,等待)......
  3. Meanwhile Transaction1 is committed and lock is released 同时Transaction1已提交并且已释放锁定
  4. Transaction2 can now proceed Transaction2现在可以继续

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: 如果您想要专门测试乐观版本控件是否正常工作,您可以执行以下操作:

  1. Obtain em1, start transaction, get your entity, commit transaction, close em1. 获取em1,启动事务,获取实体, 提交事务, 关闭 em1。
  2. Obtain em2, start transaction, get your entity, update your entity, commit transaction, close em2. 获取em2,启动事务,获取实体,更新实体,提交事务,关闭em2。
  3. Obtain em3, start transaction, attempt to update entity you've loaded in step 1 - test should fail here. 获取em3,启动事务,尝试更新您在步骤1中加载的实体 - 测试应该在这里失败。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Hibernate和MySQL超过了锁定等待超时(使用播放框架) - Lock wait timeout exceeded with Hibernate and MySQL (using play framework) 更新数据库时出错:超过了锁定等待超时 - Error updating database:Lock wait timeout exceeded 已超过READ COMMITTED锁定等待超时 - READ COMMITTED lock wait timeout exceeded 处理锁等待超时的钩子 - hook that handles Lock wait timeout exceeded 锁等待超时超过 JPA 插入 - Lock wait timeout exceeded JPA inserting 超过了锁定等待超时; 尝试在spring_Hibernate_Mysql中重新启动事务 - Lock wait timeout exceeded; try restarting transaction in spring_Hibernate_Mysql 无法获取锁定异常:锁定等待超时超过Spring SQL - Cannot aquire lock exception: lock wait timeout exceeded spring sql 获取WARN:SQL错误:1205,SQLState:41000错误:超出锁定等待超时; 尝试重新启动事务。 使用休眠保存记录 - Getting WARN: SQL Error: 1205, SQLState: 41000 ERROR: Lock wait timeout exceeded; try restarting transaction. Saving a record in using hibernate 如何解决SQL中的锁等待超时超出异常? - How to resolve Lock wait timeout exceeded exception in SQL? Spring 数据 JdbcTemplate - 多个数据源 - 超过锁定等待超时 - Spring Data JdbcTemplate - Multiple Datasources - Lock wait timeout exceeded
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM