【问题标题】:JPA/Wildfly/MsSql: GenericJDBCException: Unable to acquire JDBC ConnectionJPA/Wildfly/MsSql:GenericJDBCException:无法获取 JDBC 连接
【发布时间】:2020-11-06 04:45:16
【问题描述】:

目前我和我的团队正面临一个奇怪的问题。到目前为止,我们已经花了 4 天时间寻找解决方案。

我们正在开发一个 Java EE Web 应用程序。我们一直在使用Wildfly 14。使用Wildfly 14,没有问题。现在我们已经将 Wildfly 升级到了 18 版,之后又升级到了 19 版,现在面临以下问题。作为数据库,我们有一个 MS SQL。

数据源如下所示:

<datasource jndi-name="java:/label" pool-name="Label">
                <connection-url>jdbc:sqlserver://localhost:1433;DatabaseName=label</connection-url>
                <driver>mssql-jdbc-8.2.2.jre8.jar</driver>
                <security>
                    <user-name>label</user-name>
                    <password>label</password>
                </security>
</datasource>

persistence.xml 如下:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">


<persistence-unit name="label-pu"
    transaction-type="JTA">
    <jta-data-source>java:/label</jta-data-source>
    <properties>
        <property name="hibernate.dialect"
            value="org.hibernate.dialect.SQLServerDialect" />
    </properties>
</persistence-unit>

我们有一个 Bean,我们使用持久化单元在其中注入一个 EntityManager。当调用 bean 的方法时,我们得到了一个异常。数据源正在工作。我们在 wildfly ui 中检查了这一点。

@Dependent
public class ConstructionService {

@PersistenceContext(unitName = "label-pu")
private EntityManager em;

public List<ConstructionRecordEntity> retrieveRecordForConstruction(int contructionId) {

    String sqlSelectEmployeeId = "SELECT lfdnr, " + //
            "                            erwkz1, " + //
            "                            erwbe, " + //
            "                            erwdat " + //
            "                     FROM [label].[dbo].[aderw] where adnr = " + contructionId;//

    return em//
            .createNativeQuery(sqlSelectEmployeeId, ConstructionRecordEntity.class)//
            .getResultList();
}

在下面你可以看到我们得到的堆栈跟踪。

15:11:24,506 WARN  [org.camunda.bpm.engine.rest.exception] (default task-1) ENGINE-REST-HTTP500 javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: Unable to acquire JDBC Connection
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:154)
    at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1515)
    at org.hibernate.query.Query.getResultList(Query.java:132)
    at de._._.ConstructionService.retrieveRecordForConstruction(ConstructionService.java:26)

...

Caused by: org.hibernate.exception.GenericJDBCException: Unable to acquire JDBC Connection
    at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:47)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:113)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:99)
    at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.acquireConnectionIfNeeded(LogicalConnectionManagedImpl.java:109)
    at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.getPhysicalConnection(LogicalConnectionManagedImpl.java:136)
    at org.hibernate.engine.jdbc.internal.StatementPreparerImpl.connection(StatementPreparerImpl.java:50)
    at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$5.doPrepare(StatementPreparerImpl.java:149)
    at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$StatementPreparationTemplate.prepareStatement(StatementPreparerImpl.java:176)
    at org.hibernate.engine.jdbc.internal.StatementPreparerImpl.prepareQueryStatement(StatementPreparerImpl.java:151)
    at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:2082)
    at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:2012)
    at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1990)
    at org.hibernate.loader.Loader.doQuery(Loader.java:949)
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:351)
    at org.hibernate.loader.Loader.doList(Loader.java:2787)
    at org.hibernate.loader.Loader.doList(Loader.java:2770)
    at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2604)
    at org.hibernate.loader.Loader.list(Loader.java:2599)
    at org.hibernate.loader.custom.CustomLoader.list(CustomLoader.java:338)
    at org.hibernate.internal.SessionImpl.listCustomQuery(SessionImpl.java:2243)
    at org.hibernate.internal.AbstractSharedSessionContract.list(AbstractSharedSessionContract.java:1069)
    at org.hibernate.query.internal.NativeQueryImpl.doList(NativeQueryImpl.java:170)
    at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1506)
    ... 306 more
Caused by: java.sql.SQLException: javax.resource.ResourceException: IJ000457: Unchecked throwable in managedConnectionReconnected() cl=org.jboss.jca.core.connectionmanager.listener.TxConnectionListener@c18c68f[state=DESTROYED managed connection=org.jboss.jca.adapters.jdbc.local.LocalManagedConnection@51667cf2 connection handles=0 lastReturned=1594905084472 lastValidated=1594904382991 lastCheckedOut=1594905084468 trackByTx=false pool=org.jboss.jca.core.connectionmanager.pool.strategy.OnePool@66e3a014 mcp=SemaphoreConcurrentLinkedQueueManagedConnectionPool@685b64a3[pool=Label] xaResource=LocalXAResourceImpl@671cf884[connectionListener=c18c68f connectionManager=bec01f1 warned=false currentXid=null productName=Microsoft SQL Server productVersion=15.00.2000 jndiName=java:/label] txSync=null]
    at org.jboss.jca.adapters.jdbc.WrapperDataSource.getConnection(WrapperDataSource.java:159)
    at org.jboss.as.connector.subsystems.datasources.WildFlyDataSource.getConnection(WildFlyDataSource.java:64)
    at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:122)
    at org.hibernate.internal.NonContextualJdbcConnectionAccess.obtainConnection(NonContextualJdbcConnectionAccess.java:35)
    at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.acquireConnectionIfNeeded(LogicalConnectionManagedImpl.java:106)
    ... 325 more
Caused by: javax.resource.ResourceException: IJ000457: Unchecked throwable in managedConnectionReconnected() cl=org.jboss.jca.core.connectionmanager.listener.TxConnectionListener@c18c68f[state=DESTROYED managed connection=org.jboss.jca.adapters.jdbc.local.LocalManagedConnection@51667cf2 connection handles=0 lastReturned=1594905084472 lastValidated=1594904382991 lastCheckedOut=1594905084468 trackByTx=false pool=org.jboss.jca.core.connectionmanager.pool.strategy.OnePool@66e3a014 mcp=SemaphoreConcurrentLinkedQueueManagedConnectionPool@685b64a3[pool=Label] xaResource=LocalXAResourceImpl@671cf884[connectionListener=c18c68f connectionManager=bec01f1 warned=false currentXid=null productName=Microsoft SQL Server productVersion=15.00.2000 jndiName=java:/label] txSync=null]
    at org.jboss.jca.core.connectionmanager.AbstractConnectionManager.reconnectManagedConnection(AbstractConnectionManager.java:1055)
    at org.jboss.jca.core.connectionmanager.AbstractConnectionManager.allocateConnection(AbstractConnectionManager.java:792)
    at org.jboss.jca.adapters.jdbc.WrapperDataSource.getConnection(WrapperDataSource.java:151)
    ... 329 more
Caused by: javax.resource.ResourceException: IJ000461: Could not enlist in transaction on entering meta-aware object
    at org.jboss.jca.core.connectionmanager.tx.TxConnectionManagerImpl.managedConnectionReconnected(TxConnectionManagerImpl.java:571)
    at org.jboss.jca.core.connectionmanager.AbstractConnectionManager.reconnectManagedConnection(AbstractConnectionManager.java:977)
    ... 331 more
Caused by: javax.transaction.SystemException: Error enlisting resource in transaction=Local transaction (delegate=TransactionImple < ac, BasicAction: 0:ffffc0a83801:34f7831:5f103dd7:8e1 status: ActionStatus.ABORT_ONLY >, owner=Local transaction context for provider JBoss JTA transaction provider)
    at org.jboss.jca.core.connectionmanager.listener.TxConnectionListener$TransactionSynchronization.checkEnlisted(TxConnectionListener.java:957)
    at org.jboss.jca.core.connectionmanager.listener.TxConnectionListener.enlist(TxConnectionListener.java:394)
    at org.jboss.jca.core.connectionmanager.tx.TxConnectionManagerImpl.managedConnectionReconnected(TxConnectionManagerImpl.java:564)
    ... 332 more
Caused by: java.lang.Throwable: Failed to enlist
    at org.jboss.jca.core.connectionmanager.listener.TxConnectionListener$TransactionSynchronization.enlist(TxConnectionListener.java:1001)
    at org.jboss.jca.core.connectionmanager.listener.TxConnectionListener.enlist(TxConnectionListener.java:379)
    ... 333 more

我感谢任何提示。

【问题讨论】:

    标签: sql-server hibernate jpa jakarta-ee wildfly


    【解决方案1】:

    我们发现,这与 Camunda 有关,当我们最初认为这是一个纯粹的 Java EE 问题时。

    在 Rest Service 中使用提到的 Bean 效果很好。只有当我们将 Bean 注入到 Camunda JavaDelegate 中时才会出现问题。

    我们可以通过添加来解决这个问题

    <system-properties>
       <property name="com.arjuna.ats.arjuna.allowMultipleLastResources" value="true"/>
    </system-properties>
    

    到 Wildfly Standalone。

    它正在运行,但我们收到了警告。实际上,如果您使用 xa-datasource 来拥有一个围绕多个数据源的事务,这是必要的。但是,我们没有 xa-datasource,也不需要围绕所有内容的事务。

    据我们了解,Camunda 使用 JTA 来确保流程作业事务的安全。因此,当我们在 JavaDelegate 中进行 db 查询时,事务中有一个事务。第一个事务由 Camunda 实例化,第二个事务由我们通过使用 JPA 查询数据库来实例化。尽管如此,我还是不明白。这种情况应该很常见。所以其他人应该也经历过这种行为吧?或者可能与 MS SQL 数据库有关?

    我不明白的另一件事是,在 JavaDelegate 中使用 JPA 与 camunda 7.10 一起工作,而在最新版本 7.13 中它停止工作。

    所以,我们找到了一种解决方法,我们不再被困住了。尽管如此,这种解决方法并不令人满意,因为我们并不完全了解底层发生了什么,我们一直在寻找合适的解决方案。

    【讨论】:

      【解决方案2】:

      我很久以前就在使用 WildFly 服务器,所以这只是我的业余想法:

      事务发生了一些不好的事情。 问题点与资源征募有关: http://javadox.com/org.jboss.ironjacamar/ironjacamar-core-impl/1.2.7.Final/org/jboss/jca/core/connectionmanager/listener/TxConnectionListener.TransactionSynchronization.html#enlist()

      根据文档,数据库连接也是一个“事务资源”。所以,是的,由于某种原因,我们没有数据库连接。

      1. 可能有人出于某种原因关闭了交易?尝试通过注入 UserTransaction 或调试 TxConnectionListener 类来检查事务状态(请参阅日志)
      2. 如果事务正常,则从错误点开始调试。尝试找到导致错误的检查。您可以在 WildFly 目录中找到合适的库进行调试(使用 Far Manager、Double Commander 等)并将其连接到 IDE 以便能够在适当的位置创建断点。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-11-09
        • 2017-08-02
        • 2019-01-10
        • 1970-01-01
        • 1970-01-01
        • 2017-09-03
        • 2019-04-18
        相关资源
        最近更新 更多