休眠:尝试获取锁定时发现死锁
我在我的项目中使用休眠,并且我得到了非常简单的数据库操作的随机明显死锁。
有一个堆栈跟踪:https://gist.github.com/knyttl/8999006 - 让我感到困惑的是,第一个异常是回滚异常,然后有LockAquisition异常。
问题经常发生在类似的子句上:
@Transactional
public void setLastActivity() {
User user = em.findById(...);
user.setLastActivity(new Date());
em.merge(user);
em.flush();
}
我很困,因为我不知道这是Hibernate,MySQL还是C3P0的问题。
我的休眠配置:
<prop key="hibernate.dialect">${database.dialect}</prop>
<prop key="hibernate.hbm2ddl.auto">${database.structure}</prop>
<prop key="hibernate.connection.url">${database.connection}</prop>
<prop key="hibernate.connection.username">${database.username}</prop>
<prop key="hibernate.connection.password">${database.password}</prop>
<prop key="hibernate.connection.driver_class">${database.driver}</prop>
<prop key="hibernate.connection.shutdown">true</prop>
<prop key="hibernate.connection.writedelay">0</prop>
<prop key="hibernate.connection.characterEncoding">UTF-8</prop>
<prop key="hibernate.connection.charSet">UTF-8</prop>
<prop key="hibernate.show_sql">${database.show_sql}</prop>
<prop key="hibernate.format_sql">false</prop>
<prop key="hibernate.ejb.metamodel.generation">disabled</prop>
<!-- Use the C3P0 connection pool provider -->
<prop key="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</prop>
<prop key="hibernate.c3p0.min_size">0</prop>
<prop key="hibernate.c3p0.max_size">50</prop>
<prop key="hibernate.c3p0.timeout">120</prop>
<prop key="hibernate.c3p0.max_statements">0</prop>
<prop key="hibernate.c3p0.max_statementsPerConnection">0</prop>
<prop key="hibernate.c3p0.maxStatementsPerConnection">0</prop>
<prop key="hibernate.c3p0.idle_test_period">120</prop>
<prop key="hibernate.c3p0.acquire_increment">1</prop>
<prop key="hibernate.c3p0.numHelperThreads">8</prop>
编辑1:
- 我在上面写道,发生了明显的死锁 - 这是错误的,只有“试图获得锁时发现死锁”发生。
编辑2:
这也发生在这些方法上 - 这些方法需要用@Transactional注释:
@Transactional
public void setLastActivity() {
em.insertNative("table")
.values(...)
.execute();
}