2009-08-11 4 views
0

Ich habe ein Problem, wo ich einen Deadlock auf einem MS SQL Server bekomme. Derselbe Code läuft ohne Probleme auf MySQL.Wie verwende ich ROWLOCK mit EJB

Mein Problem ist, dass ich eine Anforderung zum Löschen eines Auftrags (der an ein Gerät angeschlossen ist), und anschließend eine Anforderung zum Erstellen eines neuen Auftrags für das gleiche Gerät erhalten. In den meisten Fällen funktioniert das ohne Probleme, aber ab und zu ist die Löschanforderung nicht beendet, wenn ich die Anforderung erhalte, einen neuen Job für das Gerät zu erstellen, und hier bekomme ich den Deadlock.

Die Anwendung läuft auf JBoss, und ich erhalte die Anfragen von einer Nachrichtenwarteschlange.

Ich habe herausgefunden, dass ich wahrscheinlich das Problem auf MSSQL mit dem rowlock-Schlüsselwort lösen konnte, aber wie aktiviere ich dies, wenn ich benannte Abfragen benutze und gleichzeitig MySQL unterstütze?

Oder gibt es eine andere Möglichkeit, um sicherzustellen, dass eine Anfrage beendet wird, bevor die nächste Anfrage für dasselbe Gerät ausgeführt wird?

A Stacktrace mit einigen Teilen entfernt, sieht wie folgt aus:

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--- 

Antwort

0

Von einem Kollegen hörte ich, dass er für eine lange Zeit versucht hat, MSSQL Verwendung rowlock statt PageLock zu machen, aber ohne Glück. Jedes Mal musste er eine Arbeit erledigen, etwa die Ausnahme abfangen und die Abfrage erneut ausführen.

In meinem Fall verwende ich EJBs, so dass ich nicht einmal sehen konnte, wie man Rowlocks mit Hibernate erzwingt.

Dass es ein Seitenschloss ist, das das Problem ist, ist die einzige Erklärung, die ich finden kann. Es gibt keine Verbindung zwischen dem, was gelöscht wird und was eingefügt wird, außer dem Gerät (das unberührt ist) und den verwendeten Tabellen.

Also die Lösung für jetzt ist es, die Ausnahme zu fangen, und die Löschung erneut auszuführen.