在Oracle到SQL Server迁移期间,jBPM + jBoss中的XA事务已中断

时间:2017-10-13 23:45:38

标签: jdbc jboss jbpm jboss-web redhat-bpm

最近开始将大型Java EE应用程序从Oracle 12c迁移到MS SQL Server 2016.大多数功能已经过测试,可以正常工作,包括Quartz Scheduler,基本JMS功能,Hibernate和EJB工作正常等等。一个奇怪的问题阻碍了进展,希望有人提出建议。

jBPM控制台可以登录并启动/暂停/停止任务。有一种情况总是会触发错误。 jBPM任务可以通过控制台发出信号并且启动完美,但是一旦第一个任务完成并且应用程序代码试图发信号通知转移到下一个任务,代码总是崩溃并出现错误。

此代码当然正在与配置了xa-datasource的Oracle连接。

错误:(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)

我无法想到SQL Server如何影响交易。

我们在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. 

触发错误的代码:

@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();
        }

    }

当然有几吨XML,但我的变化很小。基本上只是数据源已经改变,SQL Dialect并从jboss examples文件夹复制到mssql-jdbc2-service.xml。

以下是jms-ds.xml,因为错误在某种程度上表明了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>

版本:

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

(我知道有人会发表评论,所以是的,这些都是升级的时间表)

到目前为止,

SQL驱动程序尝试了:

  • sqljdbc_4.0.2206.100_enu
  • MSSQL-JDBC-6.2.1.jre7
  • MSSQL-JDBC-6.2.2.jre7
  • MSSQL-JDBC-6.3.3.jre7预览
  • 我们按照XA Transactions as posted
  • 的说明进行操作

如果我错过了重要的内容,我会添加它。

**编辑**

最后从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

1 个答案:

答案 0 :(得分:0)

**编辑 来自Microsoft的回复:

  

检查升级后,我们发现超时值基本上是一个整数值,基本上是unsigned short

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

** /编辑

因此,针对此特定问题的问题是超时值过高。

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

我已经从here重新发布了完整的示例代码以获得完整性,但是这里的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"
        )
    }
)

要重现的最小代码:

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);  
   }  
}