XA Transaction broken in jBPM+jBoss during Oracle to SQL Server migration

And*_*the 5 jboss jdbc jbpm jboss-web redhat-bpm

Recently started a migration of a large Java EE application from Oracle 12c to MS SQL Server 2016. Most functionality has been smoke tested to work OK including the Quartz Scheduler, basic JMS functions, Hibernate and EJBs working ok, etc. One weird issue has stalled progress so hoping someone might have a suggestion.

The jBPM console works to be able to log in and start/suspend/stop tasks. There is an situation that always triggers an error. The jBPM task can be signaled from with the console and it starts perfectly, but once the first task is finished and the application code tries to signal the token to move to the next task, the code always crashes with an error.

This code was working of course connected to Oracle with the xa-datasource configured.

The error: (full stacktrace)

2017-10-13 16:03:31,463 [WorkManager(2)-19] DEBUG [org.hibernate.jdbc.ConnectionManager] opening JDBC connection
2017-10-13 16:03:31,464 [WorkManager(2)-19] DEBUG [org.hibernate.util.JDBCExceptionReporter] Cannot open connection [???]
org.jboss.util.NestedSQLException: Transaction is not active: tx=TransactionImple < ac, BasicAction: -71740de1:d47b:59e10d94:f5 status: ActionStatus.ABORT_ONLY >; - nested throwable: (javax.resource.ResourceException: Transaction is not active: tx=TransactionImple < ac, BasicAction: -71740de1:d47b:59e10d94:f5 status: ActionStatus.ABORT_ONLY >)
    at org.jboss.resource.adapter.jdbc.WrapperDataSource.getConnection(WrapperDataSource.java:95)
    at org.hibernate.connection.DatasourceConnectionProvider.getConnection(DatasourceConnectionProvider.java:69)
    at org.hibernate.jdbc.ConnectionManager.openConnection(ConnectionManager.java:423)
    at org.hibernate.jdbc.ConnectionManager.getConnection(ConnectionManager.java:144)
    at org.hibernate.jdbc.AbstractBatcher.prepareQueryStatement(AbstractBatcher.java:139)
    at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1547)
    at org.hibernate.loader.Loader.doQuery(Loader.java:673)
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:236)
    at org.hibernate.loader.Loader.loadEntity(Loader.java:1860)
    at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:48)
    at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:42)
    at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:3044)
    at org.hibernate.event.def.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:395)
    at org.hibernate.event.def.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:375)
    at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:139)
    at org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:195)
    at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:103)
    at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:878)
    at org.hibernate.impl.SessionImpl.get(SessionImpl.java:815)
    at org.hibernate.impl.SessionImpl.get(SessionImpl.java:808)
    at org.jbpm.db.GraphSession.getToken(GraphSession.java:338)
    at org.jbpm.JbpmContext.getToken(JbpmContext.java:286)
    at ca.gnb.medicare.process.handling.ProcessUtilBean.signal(ProcessUtilBean.java:47)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:112)
    at org.jboss.ejb3.interceptor.InvocationContextImpl.proceed(InvocationContextImpl.java:166)
    at ca.gnb.medicare.service.interceptors.PeristenceContextInterceptor.intercept(PeristenceContextInterceptor.java:41)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.jboss.ejb3.interceptor.InvocationContextImpl.proceed(InvocationContextImpl.java:118)
    at org.jboss.ejb3.interceptor.EJB3InterceptorsInterceptor.invoke(EJB3InterceptorsInterceptor.java:63)
    at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
    at org.jboss.ejb3.entity.TransactionScopedEntityManagerInterceptor.invoke(TransactionScopedEntityManagerInterceptor.java:54)
    at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
    at org.jboss.ejb3.AllowedOperationsInterceptor.invoke(AllowedOperationsInterceptor.java:47)
    at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
    at org.jboss.aspects.tx.TxPolicy.invokeInOurTx(TxPolicy.java:79)
    at org.jboss.aspects.tx.TxInterceptor$RequiresNew.invoke(TxInterceptor.java:253)
    at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
    at org.jboss.aspects.tx.TxPropagationInterceptor.invoke(TxPropagationInterceptor.java:95)
    at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
    at org.jboss.ejb3.stateless.StatelessInstanceInterceptor.invoke(StatelessInstanceInterceptor.java:62)
    at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
    at org.jboss.aspects.security.AuthenticationInterceptor.invoke(AuthenticationInterceptor.java:77)
    at org.jboss.ejb3.security.Ejb3AuthenticationInterceptor.invoke(Ejb3AuthenticationInterceptor.java:110)
    at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
    at org.jboss.ejb3.ENCPropagationInterceptor.invoke(ENCPropagationInterceptor.java:46)
    at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
    at org.jboss.ejb3.asynchronous.AsynchronousInterceptor.invoke(AsynchronousInterceptor.java:106)
    at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
    at org.jboss.ejb3.stateless.StatelessContainer.localInvoke(StatelessContainer.java:240)
    at org.jboss.ejb3.stateless.StatelessContainer.localInvoke(StatelessContainer.java:210)
    at org.jboss.ejb3.stateless.StatelessLocalProxy.invoke(StatelessLocalProxy.java:84)
    at com.sun.proxy.$Proxy155.signal(Unknown Source)
    at ca.gnb.medicare.service.util.AbstractServiceActivator.onMessage(AbstractServiceActivator.java:143)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:112)
    at org.jboss.ejb3.interceptor.InvocationContextImpl.proceed(InvocationContextImpl.java:166)
    at ca.gnb.medicare.service.interceptors.PeristenceContextInterceptor.intercept(PeristenceContextInterceptor.java:41)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.jboss.ejb3.interceptor.InvocationContextImpl.proceed(InvocationContextImpl.java:118)
    at org.jboss.ejb3.interceptor.EJB3InterceptorsInterceptor.invoke(EJB3InterceptorsInterceptor.java:63)
    at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
    at org.jboss.ejb3.entity.TransactionScopedEntityManagerInterceptor.invoke(TransactionScopedEntityManagerInterceptor.java:54)
    at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
    at org.jboss.ejb3.AllowedOperationsInterceptor.invoke(AllowedOperationsInterceptor.java:47)
    at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
    at org.jboss.aspects.tx.TxPolicy.invokeInCallerTx(TxPolicy.java:126)
    at org.jboss.aspects.tx.TxInterceptor$Required.invoke(TxInterceptor.java:195)
    at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
    at org.jboss.ejb3.stateless.StatelessInstanceInterceptor.invoke(StatelessInstanceInterceptor.java:62)
    at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
    at org.jboss.ejb3.mdb.MessagingContainer.localInvoke(MessagingContainer.java:249)
    at org.jboss.ejb3.mdb.inflow.MessageInflowLocalProxy.delivery(MessageInflowLocalProxy.java:268)
    at org.jboss.ejb3.mdb.inflow.MessageInflowLocalProxy.invoke(MessageInflowLocalProxy.java:138)
    at com.sun.proxy.$Proxy169.onMessage(Unknown Source)
    at org.jboss.resource.adapter.jms.inflow.JmsServerSession.onMessage(JmsServerSession.java:178)
    at org.jboss.mq.SpyMessageConsumer.sessionConsumerProcessMessage(SpyMessageConsumer.java:906)
    at org.jboss.mq.SpyMessageConsumer.addMessage(SpyMessageConsumer.java:170)
    at org.jboss.mq.SpySession.run(SpySession.java:323)
    at org.jboss.resource.adapter.jms.inflow.JmsServerSession.run(JmsServerSession.java:237)
    at org.jboss.resource.work.WorkWrapper.execute(WorkWrapper.java:204)
    at org.jboss.util.threadpool.BasicTaskWrapper.run(BasicTaskWrapper.java:275)
    at EDU.oswego.cs.dl.util.concurrent.PooledExecutor$Worker.run(PooledExecutor.java:756)
    at java.lang.Thread.run(Unknown Source)
Caused by: javax.resource.ResourceException: Transaction is not active: tx=TransactionImple < ac, BasicAction: -71740de1:d47b:59e10d94:f5 status: ActionStatus.ABORT_ONLY >
    at org.jboss.resource.connectionmanager.TxConnectionManager.getManagedConnection(TxConnectionManager.java:319)
Run Code Online (Sandbox Code Playgroud)

I cannot think of how SQL Server affects the transaction.

We also get this error on SQL Server: (full sql dump)

2017-10-11 13:10:53.44 spid61      ***Stack Dump being sent to G:\MedSt\MSSQL13.MEDST\MSSQL\LOG\SQLDump0032.txt
2017-10-11 13:10:53.44 spid61      SqlDumpExceptionHandler: Process 61 generated fatal exception c0000005 EXCEPTION_ACCESS_VIOLATION. SQL Server is terminating this process.
2017-10-11 13:10:54.15 spid61      External dump process return code 0x20000001.
External dump process returned no errors.

2017-10-11 13:10:54.15 spid61      Error: 18002, Severity: 20, State: 1.
2017-10-11 13:10:54.15 spid61      Exception happened when running extended stored procedure 'xp_sqljdbc_xa_start' in the library 'SQLJDBC_XA.dll'. SQL Server is terminating process 61. Exception type: Win32 exception; Exception code: 0xc0000005. 
Run Code Online (Sandbox Code Playgroud)

Code that triggers the error:

@Stateless
public class ProcessUtilBean implements ProcessUtil{

    private static Logger log = Logger.getLogger();
    @EJB DecrementWorkCounter decrementWorkCounter;

    @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
    public void signal(long tokenId){

        JbpmContext context = null;

        try {
            context = getJbpmContext();

            log.info("attempting to get token (" + tokenId + ")");
            Token token;

            token = context.getToken(tokenId);

            token.signal(); // <-- triggers error

        } catch (Exception e) {
            e.printStackTrace();
            log.severe("Error signalling process " + e.getMessage());
        } finally {
            context.close();
        }

    }
Run Code Online (Sandbox Code Playgroud)

There are of course several tons of XML, but I've changed very little. Basically just the datasources have changed, SQL Dialect and copied over the mssql-jdbc2-service.xml from the jboss examples folder.

Here is the jms-ds.xml seeing as the errors somewhat indicate an issue here with JMS:

<?xml version="1.0" encoding="UTF-8"?>
<connection-factories>
  <!-- The JMS provider loader -->
  <mbean code="org.jboss.jms.jndi.JMSProviderLoader"
     name="jboss.mq:service=JMSProviderLoader,name=JMSProvider">
    <attribute name="ProviderName">DefaultJMSProvider</attribute>
    <attribute name="ProviderAdapterClass">
      org.jboss.jms.jndi.JNDIProviderAdapter
    </attribute>
    <!-- The combined connection factory -->
    <attribute name="FactoryRef">java:/XAConnectionFactory</attribute>
    <!-- The queue connection factory -->
    <attribute name="QueueFactoryRef">java:/XAConnectionFactory</attribute>
    <!-- The topic factory -->
    <attribute name="TopicFactoryRef">java:/XAConnectionFactory</attribute>
  </mbean>

  <!-- The server session pool for Message Driven Beans -->
  <mbean code="org.jboss.jms.asf.ServerSessionPoolLoader"
     name="jboss.mq:service=ServerSessionPoolMBean,name=StdJMSPool">
    <depends optional-attribute-name="XidFactory">jboss:service=XidFactory</depends>
    <attribute name="PoolName">StdJMSPool</attribute>
    <attribute name="PoolFactoryClass">
      org.jboss.jms.asf.StdServerSessionPoolFactory
    </attribute>
  </mbean>

  <!-- JMS XA Resource adapter, use this to get transacted JMS in beans -->
  <tx-connection-factory>
    <jndi-name>JmsXA</jndi-name>
    <xa-transaction/>
    <rar-name>jms-ra.rar</rar-name>
    <connection-definition>org.jboss.resource.adapter.jms.JmsConnectionFactory</connection-definition>
    <config-property name="SessionDefaultType" type="java.lang.String">javax.jms.Topic</config-property>
    <config-property name="JmsProviderAdapterJNDI" type="java.lang.String">java:/DefaultJMSProvider</config-property>
    <security-domain-and-application>JmsXARealm</security-domain-and-application>
    <max-pool-size>20</max-pool-size>
  </tx-connection-factory>

</connection-factories>
Run Code Online (Sandbox Code Playgroud)

Versions:

  • Java 1.7
  • jboss 4.2.3.GA
  • jbpm 3.2.6.sp1
  • hibernate 3.2.4.sp1

(I know someone will comment, so yes, these are all schedule to be upgraded)

SQL drivers tried so far:

如果我错过了一些重要的东西,我会加上它.

**编辑**

最后从sql驱动程序获得了更多信息.

2017-10-18 14:03:31,096 [JCA PoolFiller] ERROR [STDERR] Oct 18, 2017 2:03:31 PM com.microsoft.sqlserver.jdbc.TDSReader readBytes 
FINEST: TDSReader@370 (ConnectionID:166 ClientConnectionId: a62ad6a5-19e4-4187-83f5-c60a6bb1aaad) Reading 44 bytes from offset 334
2017-10-18 14:03:31,098 [JCA PoolFiller] ERROR [STDERR] Oct 18, 2017 2:03:31 PM com.microsoft.sqlserver.jdbc.TDSParser parse
FINEST: TDSReader@370 (ConnectionID:166 ClientConnectionId: a62ad6a5-19e4-4187-83f5-c60a6bb1aaad): logon: Processing TDS_ENV_CHG (0xE3)
2017-10-18 14:03:31,098 [JCA PoolFiller] ERROR [STDERR] Oct 18, 2017 2:03:31 PM com.microsoft.sqlserver.jdbc.TDSReader mark
FINEST: TDSReader@370 (ConnectionID:166 ClientConnectionId: a62ad6a5-19e4-4187-83f5-c60a6bb1aaad): Buffering from: com.microsoft.sqlserver.jdbc.TDSReaderMark@6b6611f0
2017-10-18 14:03:31,098 [JCA PoolFiller] ERROR [STDERR] Oct 18, 2017 2:03:31 PM com.microsoft.sqlserver.jdbc.TDSReader readBytes
FINEST: TDSReader@370 (ConnectionID:166 ClientConnectionId: a62ad6a5-19e4-4187-83f5-c60a6bb1aaad) Reading 8 bytes from offset 387
2017-10-18 14:03:31,099 [JCA PoolFiller] ERROR [STDERR] Oct 18, 2017 2:03:31 PM com.microsoft.sqlserver.jdbc.SQLServerConnection processEnvChange
FINER: ConnectionID:166 ClientConnectionId: a62ad6a5-19e4-4187-83f5-c60a6bb1aaad Network packet size is 8000 bytes
2017-10-18 14:03:31,099 [JCA PoolFiller] ERROR [STDERR] Oct 18, 2017 2:03:31 PM com.microsoft.sqlserver.jdbc.TDSReader reset
FINEST: TDSReader@370 (ConnectionID:166 ClientConnectionId: a62ad6a5-19e4-4187-83f5-c60a6bb1aaad): Resetting to: com.microsoft.sqlserver.jdbc.TDSReaderMark@6b6611f0
2017-10-18 14:03:31,099 [JCA PoolFiller] ERROR [STDERR] Oct 18, 2017 2:03:31 PM com.microsoft.sqlserver.jdbc.TDSReader readBytes
FINEST: TDSReader@370 (ConnectionID:166 ClientConnectionId: a62ad6a5-19e4-4187-83f5-c60a6bb1aaad) Reading 19 bytes from offset 385
2017-10-18 14:03:31,099 [JCA PoolFiller] ERROR [STDERR] Oct 18, 2017 2:03:31 PM com.microsoft.sqlserver.jdbc.TDSParser parse
FINEST: TDSReader@370 (ConnectionID:166 ClientConnectionId: a62ad6a5-19e4-4187-83f5-c60a6bb1aaad): logon: Processing TDS_DONE (0xFD)
2017-10-18 14:03:31,099 [JCA PoolFiller] ERROR [STDERR] Oct 18, 2017 2:03:31 PM com.microsoft.sqlserver.jdbc.TDSParser parse
FINEST: TDSReader@370 (ConnectionID:166 ClientConnectionId: a62ad6a5-19e4-4187-83f5-c60a6bb1aaad): logon: Processing EOF
2017-10-18 14:03:31,100 [JCA PoolFiller] ERROR [STDERR] Oct 18, 2017 2:03:31 PM com.microsoft.sqlserver.jdbc.SQLServerConnection connectInternal
FINER: ConnectionID:166 ClientConnectionId: a62ad6a5-19e4-4187-83f5-c60a6bb1aaad End of connect
2017-10-18 14:03:31,100 [JCA PoolFiller] ERROR [STDERR] Oct 18, 2017 2:03:31 PM com.microsoft.sqlserver.jdbc.SQLServerXAConnection <init>
FINER: Created an internal control connectionConnectionID:166 ClientConnectionId: a62ad6a5-19e4-4187-83f5-c60a6bb1aaad for SQLServerXAConnection:81 Physical connection:ConnectionID:165 ClientConnectionId: 78fd8cb2-78ff-44d7-9cae-e20e6256b37e
2017-10-18 14:03:31,100 [JCA PoolFiller] ERROR [STDERR] Oct 18, 2017 2:03:31 PM com.microsoft.sqlserver.jdbc.SQLServerXAConnection <init>
FINER: SQLServerXADataSource:1 user:MEDST3
2017-10-18 14:03:31,100 [JCA PoolFiller] ERROR [STDERR] Oct 18, 2017 2:03:31 PM com.microsoft.sqlserver.jdbc.SQLServerXADataSource getXAConnection
FINER: SQLServerXADataSource:1 user:MEDST3SQLServerXAConnection:81
2017-10-18 14:03:31,100 [JCA PoolFiller] ERROR [STDERR] Oct 18, 2017 2:03:31 PM com.microsoft.sqlserver.jdbc.SQLServerXADataSource getXAConnection
FINER: SQLServerXADataSource:1 Start get physical connection.
2017-10-18 14:03:31,100 [JCA PoolFiller] ERROR [STDERR] Oct 18, 2017 2:03:31 PM com.microsoft.sqlserver.jdbc.SQLServerXADataSource getXAConnection
FINE: SQLServerXADataSource:1 End get physical connection, ConnectionID:165 ClientConnectionId: 78fd8cb2-78ff-44d7-9cae-e20e6256b37e
2017-10-18 14:03:31,100 [JCA PoolFiller] ERROR [STDERR] Oct 18, 2017 2:03:31 PM com.microsoft.sqlserver.jdbc.SQLServerXADataSource:1 getXAConnection
FINER: RETURN SQLServerXAConnection:81
2017-10-18 14:03:31,101 [JCA PoolFiller] ERROR [STDERR] Oct 18, 2017 2:03:31 PM com.microsoft.sqlserver.jdbc.SQLServerPooledConnection getConnection
FINER: SQLServerXAConnection:81 user:(default).
2017-10-18 14:03:31,101 [JCA PoolFiller] ERROR [STDERR] Oct 18, 2017 2:03:31 PM com.microsoft.sqlserver.jdbc.SQLServerPooledConnection getConnection
FINE: SQLServerXAConnection:81 Physical connection, ConnectionID:165 ClientConnectionId: 78fd8cb2-78ff-44d7-9cae-e20e6256b37e
2017-10-18 14:03:31,098 [main] TRACE [org.jboss.web.tomcat.service.WebAppClassLoader] filter name=ca.gnb.medicare.application.claim.manage.SelectServiceProvider$1, exclude=false
2017-10-18 14:03:31,101 [main] DEBUG [org.apache.catalina.loader.WebappClassLoader]   Searching local repositories
2017-10-18 14:03:31,101 [JCA PoolFiller] ERROR [STDERR] Oct 18, 2017 2:03:31 PM com.microsoft.sqlserver.jdbc.SQLServerPooledConnection getConnection
FINE: SQLServerXAConnection:81 proxy  ProxyConnectionID:81 is returned.
2017-10-18 14:03:31,101 [main] TRACE [org.jboss.web.tomcat.service.WebAppClassLoader] findClass(ca.gnb.medicare.application.claim.manage.SelectServiceProvider$1) called
2017-10-18 14:03:31,101 [main] DEBUG [org.apache.catalina.loader.WebappClassLoader]     findClass(ca.gnb.medicare.application.claim.manage.SelectServiceProvider$1)
2017-10-18 14:03:31,101 [JCA PoolFiller] ERROR [STDERR] Oct 18, 2017 2:03:31 PM com.microsoft.sqlserver.jdbc.SQLServerConnection:165 getTransactionIsolation
FINER: ENTRY
2017-10-18 14:03:31,101 [main] TRACE [org.apache.catalina.loader.WebappClassLoader]       findClassInternal(ca.gnb.medicare.application.claim.manage.SelectServiceProvider$1)
2017-10-18 14:03:31,101 [WorkManager(2)-19] INFO  [org.hibernate.impl.SessionFactoryImpl] building session factory
2017-10-18 14:03:31,101 [JCA PoolFiller] ERROR [STDERR] Oct 18, 2017 2:03:31 PM com.microsoft.sqlserver.jdbc.SQLServerConnection:165 getTransactionIsolation
FINER: RETURN 2 (this is = TRANSACTION_READ_COMMITTED) https://docs.oracle.com/javase/7/docs/api/constant-values.html#java.sql
2017-10-18 14:03:31,101 [JCA PoolFiller] ERROR [STDERR] Oct 18, 2017 2:03:31 PM com.microsoft.sqlserver.jdbc.SQLServerConnection:165 isReadOnly
FINER: ENTRY
2017-10-18 14:03:31,101 [WorkManager(2)-19] DEBUG [org.hibernate.impl.SessionFactoryImpl] Session factory constructed with filter configurations : {}
2017-10-18 14:03:31,101 [JCA PoolFiller] ERROR [STDERR] Oct 18, 2017 2:03:31 PM com.microsoft.sqlserver.jdbc.SQLServerConnection:165 isReadOnly
FINER: RETURN false
Run Code Online (Sandbox Code Playgroud)

And*_*the 0

**微软的编辑回复:

在检查我的升级后,我们发现超时值基本上在一个整数值范围内,该整数值基本上是一个unsigned Short

因此最大 XA 超时值为 65,535。

** /编辑

因此,这个特定问题的问题在于超时值过高。

要么最初的开发人员认为批处理需要 333.33 小时,要么他们只是随机选择了 1,200,000 秒的数字。甲骨文不在乎。SQL Server SQLJDBC_XA.DLL 可以。我还没有找到记录的最大值,但降低该值可以解决问题。

为了完整性,我从这里重新发布了完整的示例代码,但罪魁祸首是这里的 1,200,000 值:

@PoolClass(value=org.jboss.ejb3.StrictMaxPool.class, maxSize=20, timeout=1200000)
@MessageDriven(
    mappedName=ClaimsBatchInstigatorBean.QUEUE_NAME,
    activationConfig={
        @ActivationConfigProperty(
            propertyName="destination",
            propertyValue=ClaimsBatchInstigatorBean.QUEUE_NAME
        ),
        @ActivationConfigProperty(
            propertyName="destinationType",
            propertyValue="javax.jms.Queue"
        ),
        @ActivationConfigProperty(
            propertyName = "transactionTimeout",
            propertyValue = "1200000"
        ),
        @ActivationConfigProperty(
                propertyName="maxSession",
                propertyValue="15"
        )
    }
)
Run Code Online (Sandbox Code Playgroud)

重现的最少代码:

package com.******.test;

import java.net.Inet4Address;  
import java.sql.*;  
import java.util.Random;
import javax.transaction.xa.*;  
import javax.sql.*;  
import com.microsoft.sqlserver.jdbc.*;  

public class testXA {  

   public static void main(String[] args) throws Exception {  

      // Create variables for the connection string.  
      String prefix = "jdbc:sqlserver://";  
      String serverName = "******";  
      int portNumber = ******;  
      String databaseName = "******";   
      String user = "******";   
      String password = "******";  
      String connectionUrl = prefix + serverName + ":" + portNumber  
         + ";databaseName=" + databaseName + ";user=" + user + ";password=" + password;  

      try {  
         // Establish the connection.  
         Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");  
         Connection con = DriverManager.getConnection(connectionUrl);  

         // Create a test table.  
         Statement stmt = con.createStatement();  
         try {  
            stmt.executeUpdate("DROP TABLE XAMin");   
         }  
         catch (Exception e) {  
         }  
         stmt.executeUpdate("CREATE TABLE XAMin (f1 int, f2 varchar(max))");  
         stmt.close();  
         con.close();  

         // Create the XA data source and XA ready connection.  
         SQLServerXADataSource ds = new SQLServerXADataSource();  
         ds.setUser(user);  
         ds.setPassword(password);  
         ds.setServerName(serverName);  
         ds.setPortNumber(portNumber);  
         ds.setDatabaseName(databaseName);  
         XAConnection xaCon = ds.getXAConnection();  
         con = xaCon.getConnection();  
         con.setAutoCommit(false);

         // Get a unique Xid object for testing.  
         XAResource xaRes = null;  
         Xid xid = null;  
         xid =  XidImpl.getUniqueXid(1);

         // Get the XAResource object and set the timeout value.  
         xaRes = xaCon.getXAResource();  

         //  xaRes.setTransactionTimeout(0);   <-- no error
         //  xaRes.setTransactionTimeout(30000);   <-- no error
         xaRes.setTransactionTimeout(1200000);   //<--- error!


         // Perform the XA transaction.  
         System.out.println("Write -> xid = " + xid.toString());  
         xaRes.start(xid,XAResource.TMNOFLAGS);  
         PreparedStatement pstmt =   
         con.prepareStatement("INSERT INTO XAMin (f1,f2) VALUES (?, ?)");  
         pstmt.setInt(1,1);  
         pstmt.setString(2,xid.toString());  
         pstmt.executeUpdate();  

         // Commit the transaction.  
         xaRes.end(xid,XAResource.TMSUCCESS);  
         xaRes.commit(xid,true);  

         // Cleanup.  
         con.close();  
         xaCon.close();  

         // Open a new connection and read back the record to verify that it worked.  
         con = DriverManager.getConnection(connectionUrl);  
         ResultSet rs = con.createStatement().executeQuery("SELECT * FROM XAMin");  
         rs.next();  
         System.out.println("Read  -> xid = " + rs.getString(2));  
         rs.close();  
         con.close();  
      }   

      // Handle any errors that may have occurred.  
      catch (Exception e) {  
         e.printStackTrace();  
      }  
   }  
}  

class XidImpl implements Xid {  

   public int formatId;  
   public byte[] gtrid;  
   public byte[] bqual;  
   public byte[] getGlobalTransactionId() {return gtrid;}  
   public byte[] getBranchQualifier() {return bqual;}  
   public int getFormatId() {return formatId;}  

   XidImpl(int formatId, byte[] gtrid, byte[] bqual) {  
      this.formatId = formatId;  
      this.gtrid = gtrid;  
      this.bqual = bqual;  
   }  

   public String toString() {  
      int hexVal;  
      StringBuffer sb = new StringBuffer(512);  
      sb.append("formatId=" + formatId);  
      sb.append(" gtrid(" + gtrid.length + ")={0x");  
      for (int i=0; i<gtrid.length; i++) {  
         hexVal = gtrid[i]&0xFF;  
         if ( hexVal < 0x10 )  
            sb.append("0" + Integer.toHexString(gtrid[i]&0xFF));  
         else  
            sb.append(Integer.toHexString(gtrid[i]&0xFF));  
         }  
         sb.append("} bqual(" + bqual.length + ")={0x");  
         for (int i=0; i<bqual.length; i++) {  
            hexVal = bqual[i]&0xFF;  
            if ( hexVal < 0x10 )  
               sb.append("0" + Integer.toHexString(bqual[i]&0xFF));  
            else  
               sb.append(Integer.toHexString(bqual[i]&0xFF));  
         }  
         sb.append("}");  
         return sb.toString();  
      }  

      // Returns a globally unique transaction id.  
      static byte [] localIP = null;  
      static int txnUniqueID = 0;  
      static Xid getUniqueXid(int tid) {  

      Random rnd = new Random(System.currentTimeMillis());  
      txnUniqueID++;  
      int txnUID = txnUniqueID;  
      int tidID = tid;  
      int randID = rnd.nextInt();  
      byte[] gtrid = new byte[64];  
      byte[] bqual = new byte[64];  
      if ( null == localIP) {  
         try {  
            localIP = Inet4Address.getLocalHost().getAddress();  
         }  
         catch ( Exception ex ) {  
            localIP =  new byte[] { 0x01,0x02,0x03,0x04 };  
         }  
      }  
      System.arraycopy(localIP,0,gtrid,0,4);  
      System.arraycopy(localIP,0,bqual,0,4);  

      // Bytes 4 -> 7 - unique transaction id.  
      // Bytes 8 ->11 - thread id.  
      // Bytes 12->15 - random number generated by using seed from current time in milliseconds.  
      for (int i=0; i<=3; i++) {  
         gtrid[i+4] = (byte)(txnUID%0x100);  
         bqual[i+4] = (byte)(txnUID%0x100);  
         txnUID >>= 8;  
         gtrid[i+8] = (byte)(tidID%0x100);  
         bqual[i+8] = (byte)(tidID%0x100);  
         tidID >>= 8;  
         gtrid[i+12] = (byte)(randID%0x100);  
         bqual[i+12] = (byte)(randID%0x100);  
         randID >>= 8;  
      }  
      return new XidImpl(0x20003, gtrid, bqual);  
   }  
}  
Run Code Online (Sandbox Code Playgroud)