尽管使用CallableStatement在db中成功写入了数据,但报告了事务失败

时间:2018-09-27 11:27:29

标签: jdbc websphere

尽管数据已成功保存在表中,但我们仍遇到事务失败。与已配置的事务数据库超时相比,查询执行时间要短得多。

这是一个基于应用程序间请求响应的消息传递的场景,两个应用程序都分别部署在WAS服务器上。

[9/21/18 12:36:02:432 CEST] 00000021 TimeoutManage I   WTRN0124I: When the timeout occurred the thread with which the transaction is, or was most recently, associated was Thread[Messenger-Listener-95,5,main]. The stack trace of this thread when the timeout occurred was: 
    java.net.SocketInputStream.socketRead0(Native Method)
    java.net.SocketInputStream.read(SocketInputStream.java:140)
    oracle.net.ns.Packet.receive(Packet.java:300)
    oracle.net.ns.DataPacket.receive(DataPacket.java:106)
    oracle.net.ns.NetInputStream.getNextPacket(NetInputStream.java:315)
    oracle.net.ns.NetInputStream.read(NetInputStream.java:260)
    oracle.net.ns.NetInputStream.read(NetInputStream.java:185)
    oracle.net.ns.NetInputStream.read(NetInputStream.java:102)
    oracle.jdbc.driver.T4CSocketInputStreamWrapper.readNextPacket(T4CSocketInputStreamWrapper.java:124)
    oracle.jdbc.driver.T4CSocketInputStreamWrapper.read(T4CSocketInputStreamWrapper.java:80)
    oracle.jdbc.driver.T4CMAREngine.unmarshalUB1(T4CMAREngine.java:1137)
    oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:290)
    oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:192)
    oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:531)
    oracle.jdbc.driver.T4CCallableStatement.doOall8(T4CCallableStatement.java:204)
    oracle.jdbc.driver.T4CCallableStatement.executeForRows(T4CCallableStatement.java:1041)
    oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1329)
    oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3584)
    oracle.jdbc.driver.OraclePreparedStatement.execute(OraclePreparedStatement.java:3685)
    oracle.jdbc.driver.OracleCallableStatement.execute(OracleCallableStatement.java:4714)
    oracle.jdbc.driver.OraclePreparedStatementWrapper.execute(OraclePreparedStatementWrapper.java:1376)
    com.ibm.ws.rsadapter.jdbc.WSJdbcPreparedStatement.execute(WSJdbcPreparedStatement.java:618)
    com.rbc.spp.wfl.WorkflowListener.Insert_CDSC_MF_IMPORT(WorkflowListener.java:98)
    com.rbc.spp.wfl.WorkflowListener.onMessage(WorkflowListener.java:71)
    com.rbc.commons.eden.listener.ESBListener.doBusiness(ESBListener.java:119)
    com.rbc.commons.eden.listener.ESBListener.doBusiness(ESBListener.java:26)
    com.rbc.commons.eden.listener.AbstractListener.onMessage(AbstractListener.java:68)
    com.rbcdexia.eden.internal.messenger.InternalMessenger.processMessage(InternalMessenger.java:972)
    com.rbcdexia.eden.internal.connector.enterprise.Listener.getAndProcess(Listener.java:149)
    com.rbcdexia.eden.internal.connector.AbstractListener.run(AbstractListener.java:83)
    org.springframework.scheduling.commonj.DelegatingWork.run(DelegatingWork.java:61)
    com.ibm.ws.asynchbeans.J2EEContext$RunProxy.run(J2EEContext.java:266)
    java.security.AccessController.doPrivileged(AccessController.java:384)
    javax.security.auth.Subject.doAs(Subject.java:495)
    com.ibm.websphere.security.auth.WSSubject.doAs(WSSubject.java:131)
    com.ibm.websphere.security.auth.WSSubject.doAs(WSSubject.java:89)
    com.ibm.ws.asynchbeans.J2EEContext$DoAsProxy.run(J2EEContext.java:337)
    java.security.AccessController.doPrivileged(AccessController.java:413)
    com.ibm.ws.asynchbeans.J2EEContext.run(J2EEContext.java:1146)
    com.ibm.ws.asynchbeans.WorkWithExecutionContextImpl.go(WorkWithExecutionContextImpl.java:199)
    com.ibm.ws.asynchbeans.CJWorkItemImpl.run(CJWorkItemImpl.java:188)
    com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1662)

发生的代码段是:

Connection connection = null;
        CallableStatement callableStatement = null;

        try {
            connection = dataSource.getConnection();
            callableStatement = connection.prepareCall("{ call LOAD_DATA(?,TO_CLOB(?)) }");
            callableStatement.setString(1, fileName);
            callableStatement.setString(2, messageContent);
            callableStatement.execute();
            LOG.info("Data inserted successfully into REQUD table.");
        } catch (SQLException ex) {
            LOG.error(ex.getMessage());
            throw new DatabaseException(ex);
        } finally {
// to close connection/statements objects
            DbUtils.closeQuietly(callableStatement);
            DbUtils.closeQuietly(connection);

        }

没有超时问题,没有线程互锁,发生此问题时,DB完全可用,而没有任何停机时间问题。

1 个答案:

答案 0 :(得分:0)

您看到事务管理器发出超时警告的事实意味着该操作是较大事务的一部分,通常由UserTransaction.begin / commit封装,或者由容器管理,因此边界不会明确显示在应用程序代码中。该代码段仅显示与数据库相关的事务部分。您如何确定数据已成功保存到表中?消息LOG.info("Data inserted successfully into REQUD table.");的出现不能保证这一点。它仅显示了事务中的一定数量的进度,所有这些进度最终都可能被提交或回滚。在事务超时的情况下,应始终回滚它,如果不回滚则是事务管理器错误。如果您确认更新确实已持久保存在数据库中,则应该与IBM一起处理事务管理器问题。