Java 如何修复';SQLException SQL0913';在不同线程中调用SQL update之后

Java 如何修复';SQLException SQL0913';在不同线程中调用SQL update之后,java,db2,db2-400,jboss-eap-6,javax.persistence,Java,Db2,Db2 400,Jboss Eap 6,Javax.persistence,我正在调用一个方法,该方法对DB2数据库中的单个数据集执行SQL更新。在接收来自ActiveMQ队列的消息后,该方法在不同线程中自动调用。它在2秒内被调用了5次,但由于第一次调用在数据集上设置了写锁,因此接下来的3次调用必须等待。第一个调用完成更新后,第二个调用不执行更新,而是运行一个新的方法调用(行中的第五个调用)。问题是,中间的三个调用没有识别,写锁被释放,并且在超时1分钟后抛出SQLException,错误为SQL0913 Caused by: java.sql.SQLException:

我正在调用一个方法,该方法对DB2数据库中的单个数据集执行SQL更新。在接收来自ActiveMQ队列的消息后,该方法在不同线程中自动调用。它在2秒内被调用了5次,但由于第一次调用在数据集上设置了写锁,因此接下来的3次调用必须等待。第一个调用完成更新后,第二个调用不执行更新,而是运行一个新的方法调用(行中的第五个调用)。问题是,中间的三个调用没有识别,写锁被释放,并且在超时1分钟后抛出SQLException,错误为SQL0913

Caused by: java.sql.SQLException: [SQL0913] Zeile oder Objekt PR1BAFPU5 der Art *FILE in DAKDTA wird verwendet. Ursache  . . . . :  Das angeforderte Objekt PR1BAFPU5 der Art *FILE in der Bibliothek DAKDTA wird gerade von einem anderen Anwendungsprozess verwendet, oder eine Zeile im Objekt wird von einem anderen Anwendungsprozess oder einem anderen Cursor in diesem Anwendungsprozess verwendet. Fehlerbeseitigung:  Die vorherigen Nachrichten im Jobprotokoll aufrufen (Befehl DSPJOBLOG) oder im interaktiven SQL F10 (Nachrichten im Jobprotokoll anzeigen) in dieser Anzeige drücken, um zu bestimmen, ob es sich um eine Wartezeitüberschreitung für eine Objekt- oder Satzsperre handelt. Einen der folgenden Schritte durchführen: -- Wird ein Objekt durch einen anderen Anwendungsprozess gesperrt, die SQL-Anweisung wiederholen, wenn das Objekt nicht verwendet wird. Mit dem Befehl WRKOBJLCK (Mit Objektsperren arbeiten) kann festgestellt werden, von wem das Objekt gerade verwendet wird. -- Ist das Objekt ein Schema und wurde versucht, in diesem Schema eine Tabelle, eine Sicht oder einen Index unter COMMIT-Steuerung zu erstellen, wird möglicherweise für dieses Schema gerade eine Operation zum "Sichern im aktiven Zustand" von einem anderen Job im System durchgeführt. Ist die Operation zum "Sichern im aktiven Zustand" abgeschlossen, die Anforderung wiederholen. -- Wird ein Satz durch einen anderen Anwendungsprozess gesperrt, die SQL-Anweisung wiederholen, wenn der Satz nicht verwendet wird. Mit dem Befehl DSPRCDLCK (Satzsperren anzeigen)kann festgestellt werden, von wem der Satz gerade verwendet wird. -- Wird der Satz von einem anderen Cursor in demselben Anwendungsprozess gesperrt, muss eine Anweisung COMMIT, ROLLBACK oder eine andere Anweisung FETCH für den Cursor ausgegeben werden, der die Sperre verursacht, bevor diese SQL-Anweisung ausgegeben wird. Tritt dieser Fehler häufig auf, mit dem Befehl CHGPF (Physische Datei ändern), CHGLF (Logische Datei ändern) oder OVRDBF (Datenbankdatei überschreiben) die Wartezeitüberschreitung für das Objekt oder den Satz ändern. 
        at com.ibm.as400.access.JDError.createSQLExceptionSubClass(JDError.java:860) [jt400-jdbc4-7.8.jar:JTOpen 7.8] 
        at com.ibm.as400.access.JDError.throwSQLException(JDError.java:692) [jt400-jdbc4-7.8.jar:JTOpen 7.8] 
        at com.ibm.as400.access.JDError.throwSQLException(JDError.java:662) [jt400-jdbc4-7.8.jar:JTOpen 7.8] 
        at com.ibm.as400.access.AS400JDBCStatement.commonExecute(AS400JDBCStatement.java:1025) [jt400-jdbc4-7.8.jar:JTOpen 7.8] 
        at com.ibm.as400.access.AS400JDBCPreparedStatement.executeUpdate(AS400JDBCPreparedStatement.java:1649) [jt400-jdbc4-7.8.jar:JTOpen 7.8] 
        at org.jboss.jca.adapters.jdbc.WrappedPreparedStatement.executeUpdate(WrappedPreparedStatement.java:493) 
        at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:186) [hibernate-core-4.2.27.Final-redhat-1.jar:4.2.27.Final-redhat-1] 
        ... 143 more 
该数据库是一个IBMDB2数据库(版本7.2),我的程序运行在JBoss EAP-6.4上。从日志来看,第一个调用似乎需要几秒钟才能执行,在接下来的三个调用之间等待第一个调用。但在第一个调用完成执行后,接下来的三个调用不会继续进行

public void updateBerthTimeConflictFlag4BerthArrival(boolean conflict, String berthArrivalId) { 
                Query updateQuery = em.createNativeQuery("update PR1BERTHARRIVAL_FLZ set berthTimeConflict = :conflict where id = :id"); 
                updateQuery.setParameter("conflict", conflict ? 1 : 0); 
                updateQuery.setParameter("id", berthArrivalId); 
                updateQuery.executeUpdate(); 
        } 

我希望,在第一次调用完成后,SQL update的接下来三次调用将按照调用的顺序执行。

我们在几次之前也遇到过同样的问题,我们遵循以下步骤:

问题(摘要)

当应用程序使用JDBC从表中读取大量记录并使用BMP实体bean从表中删除记录时,会出现错误“java.sql.SQLException:[SQL0913]行或对象F55500 in type*FILE in use”

原因

异常表示行或对象正在使用中

解决问题

在读取大量记录的JDBC程序中,需要确保关闭所有连接,以便释放所有资源。 如果没有释放连接的直接方法,则重新启动数据库将删除所有打开的连接,但如果没有其他释放连接的替代方法,则这将是最后一种措施。 不要使用JDBC程序,而是创建一个单独的会话bean来包含对数据库的查询。会话bean的事务设置应为RequiresNew。SQL语句现在在一个新的单独事务中运行。方法完成运行后,事务结束,表被释放以供BMP实体bean删除


这里原始的

更新方法需要更快地提交。搜索到的更新需要正确索引。按照SQL0913消息文本中的建议查看是否可以从服务器端获取更多详细信息。还指定Db2-for-i系列服务器版本。Db2服务器版本为7.2。根据短信中的建议,我现在什么都没有得到,因为这个异常已经发生在几天前了,我现在无法复制它。