论坛首页 入门讨论版 Hibernate

听说robbin解决过一个死锁的事,我想请教了下

浏览 6468 次
该帖已经被评为新手帖
作者 正文
时间:2006-12-01
15:33:57,796 WARN [JDBCExceptionReporter] SQL Error: 1205, SQLState: 40001
15:33:57,796 ERROR [JDBCExceptionReporter] 事务(进程 ID 53)与另一个进程被死锁在 锁 资源上,并且已被选作死锁牺牲品。请重新运行该事务。
15:33:57,796 ERROR [AbstractFlushingEventListener] 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:82)
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:70)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:162)
at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:72)
at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:67)
at org.hibernate.jdbc.AbstractBatcher.prepareBatchStatement(AbstractBatcher.java:131)
at org.hibernate.persister.BasicEntityPersister.update(BasicEntityPersister.java:1776)
at org.hibernate.persister.BasicEntityPersister.updateOrInsert(BasicEntityPersister.java:1732)
at org.hibernate.persister.BasicEntityPersister.update(BasicEntityPersister.java:1969)
at org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:72)
at org.hibernate.impl.ActionQueue.execute(ActionQueue.java:240)
at org.hibernate.impl.ActionQueue.executeActions(ActionQueue.java:224)
at org.hibernate.impl.ActionQueue.executeActions(ActionQueue.java:138)
at org.hibernate.event.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:265)
at org.hibernate.event.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:24)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:814)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:75)
at test.com.philo.workflow.PerformanceTest$Runner4Test2ThreadsPO.runOne(PerformanceTest.java:163)
at test.com.philo.workflow.PerformanceTest$Runner4Test2ThreadsPO.run(PerformanceTest.java:62)
at java.lang.Thread.run(Thread.java:534)
   
时间:2006-12-01
我写的是一个中间件,服务端的结构大体是SB+HIBERNATE,现在这个中间件连接ORACLE没有问题,但连接SQLSERVER2000或2005都会出现这个问题,是并发时出现的(甚至2个并发就会出现了)。为了解决这个问题,我现在正在简化我的程序,如只有POJO而没有VO和BO,用2个线程对POJO的简单SAVE和UPDATE做测试,结果还是出现死锁问题。

我还努力把纯JDBC但SQL语句列表和HIBERNATE生成的非常接近的简化版本写好,然后用LOADRUNNER压一下(我平时用多线程压,发现中间件版本和只用POJO的HIBERNATE简化版本都会出现死锁问题,但纯JDBC版本这样压不死)。

我也有点怀疑是HIBENATE配置参数没配置好,或者是我的映射模型有问题(我在父中的子集合比较多地用了MAP,目的是快速访问单一的子),目前SQLSERVER版本就要交货了,我自己尝试了大概有三个星期了,还是没解决,什么JDBC驱动之类的都试了,甚至把SQLSERVER从2000升级到了2005都做了,就是死锁!

谢谢各位遇到过的朋友帮忙看一下,如果有必要,我逐渐把配置文件、映射文件和部分JAVA代码与贴上来。谢谢
   
0 请登录后投票
时间:2006-12-01
记得外键要加索引

找一下你的数据库日志,看一下是什么引起的, 哪些数据被锁, 什么原因。
   
0 请登录后投票
时间:2006-12-04
日志里还没找到这样的信息,外键我由于不用数据库的正式外键,因此索引倒不会忘了加,而且我的外键一律是fdXXXId,所以也不容易忘记或遗漏

目前已经知道的就是2个主要的表会出现死锁,发生在并发的update语句

##############补充更正:死锁信息已经放在后面的贴子中了##########
   
0 请登录后投票
时间:2006-12-04
我没有添加版本控制,不知它对update时发生的锁定有无关系?
   
0 请登录后投票
时间:2007-02-01
搞不定啊,很久了,不过近来看了一些资料,对SQLSERVER的锁有了一定的认识,已经抓到几种死锁的图了。下面是其中的一个

   
0 请登录后投票
时间:2007-02-01
把连接池连接数变为一
   
0 请登录后投票
时间:2007-02-01
死锁通常与你的设计有关,使用了事务吗,是不是在一个事务中有多个UPDATE反复更新一个或多个但有关联的表。多检查一下你的设计吧
   
0 请登录后投票
时间:2007-02-01
"但有关联的表"是什么意思,你是说有还是说没有?我确实在反复更新,为了处理这个问题,我只映射了2个实体:流程(P)和流程节点(A),我的批处理有大量更新流程和流程节点的语句,发现P的主键索引和A的主键索引会出现相互等待的情形

更奇怪的是,我还遇到A的主键索引和A的主索引相互等待的情形,我不知道后一种情形是如何发生的,因为我的压力测试并没有用不同线程操作相同的数据,它们操作的流程实例并不相同

报的都是KEYLOCK引起的死锁。
   
0 请登录后投票
时间:2007-02-01
抛出异常的爱 写道
把连接池连接数变为一


你不想并发啦?
   
0 请登录后投票
论坛首页 入门讨论版 Hibernate

跳转论坛:
JavaEye推荐