我有一个问题,我在MS SQL Server上遇到死锁。相同的代码在MySQL上运行没有问题。
我的问题是我收到删除作业(附加到设备)的请求,之后我收到了为同一设备创建新作业的请求。大多数情况下这没有任何问题,但是当我收到为设备创建新作业的请求时,删除请求偶尔会完成,这就是我遇到死锁的地方。
应用程序在JBoss上运行,我从消息队列接收请求。
我发现我可能可以使用rowlock关键字解决MSSQL上的问题,但是如何在使用命名查询时启用它并同时支持MySQL?
或者还有其他方法可以确保在运行同一设备的下一个请求之前完成一个请求吗?
删除了某些部分的堆栈跟踪如下所示:
2009-08-11 10:03:22,621 WARN [org.hibernate.util.JDBCExceptionReporter] SQL Error: 1205, SQLState: 40001
2009-08-11 10:03:22,621 ERROR [org.hibernate.util.JDBCExceptionReporter] Transaction (Process ID 200) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
2009-08-11 10:03:22,621 ERROR [org.hibernate.event.def.AbstractFlushingEventListener] Could not synchronize database state with session
org.hibernate.exception.LockAcquisitionException: could not delete: [dme.dm.device.Task#131]
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:82)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
---cut cut cut---
Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: Transaction (Process ID 200) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(Unknown Source)
---cut cut cut---
答案 0 :(得分:0)
从同事那里我听说他很长时间以来都试图让MSSQL使用rowlock而不是pagelock,但没有运气。每次他不得不做一个解决方法,比如捕获异常并重新运行查询。
在我的情况下,我正在使用EJB,所以我甚至看不到如何使用hibernate强制执行行锁。
这是一个问题的分页锁,是我能找到的唯一解释。除了设备(未触及的)和使用的表之外,删除的内容和插入的内容之间没有任何关联。
所以现在的解决方案是捕获异常,然后重新运行删除。