5

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

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

该代码当然可以在配置了 xa-datasource 的情况下连接到 Oracle。

错误:(完整的堆栈跟踪

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 上也收到此错误:(完整的 sql 转储

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 方言并从 jboss 示例文件夹中复制了 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
  • 休眠 3.2.4.sp1

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

到目前为止尝试过的 SQL 驱动程序:

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

** 编辑 **

终于从 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
4

1 回答 1

0

**编辑来自微软的回应:

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

所以最大 XA Timeout 值为 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"
        )
    }
)

重现的最少代码:

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);  
   }  
}  
于 2017-10-24T12:52:17.447 回答