You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WebSphere Liberty下RESOURCE_LOCAL事务提交报DSRA9350E错误求助

问题描述

运行在WebSphere Liberty上的老项目,使用JPA(EclipseLink)连接MSSQL Server,persistence.xml配置如下:

<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="dbMyApp" transaction-type="RESOURCE_LOCAL">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    <non-jta-data-source>jdbc/myAppDatasource</non-jta-data-source>
    <class>com.xyz.hook</class>
    <class>com.xyz.CMparm</class>
    <exclude-unlisted-classes>false</exclude-unlisted-classes>
    <shared-cache-mode>NONE</shared-cache-mode>
    <validation-mode>NONE</validation-mode>
    <properties>
      <property name="javax.persistence.schema-generation.database.action" value="create"/>
      <property name="eclipselink.ddl-generation" value="create-or-extend-tables"/>
      <property name="eclipselink.create-ddl-jdbc-file-name" value="createDB.sql"/>
      <property name="eclipselink.drop-ddl-jdbc-file-name" value="dropDB.sql"/>
      <property name="eclipselink.ddl-generation.output-mode" value="database"/>
      <property name="eclipselink.logging.level" value="SEVERE"/>
    </properties>
  </persistence-unit>
</persistence>

相关控制器方法代码:

@Post
public Response postRepository(Repository repository) throws Exception
{
    try {
            entityMgr = getEntityManager();
            entityMgr.getTransaction().begin();
            
            try
            {
                validateRepositoryParameters(repository);
            }
            catch (Exception e)
            {
                return Response.status(Response.Status.BAD_REQUEST).entity(new ErrorResponse(e.getMessage())).build();
            }

            entityMgr.persist(repository);
            entityMgr.getTransaction().commit();
                
        }
        catch (javax.persistence.EntityExistsException e)
        {
            return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(new ErrorResponse(e.getMessage())).build();
        }
}

项目采用RESOURCE_LOCAL事务类型,全应用手动管理事务,但创建Repository时触发错误:

[2025-02-03, 12:11:43:984 EST] 00000033 SystemErr R javax.persistence.RollbackException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.7.15.v20240516-53511fdbd8): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLException: DSRA9350E: Operation Connection.commit is not allowed during a global transaction.
Error Code: 0
[2025-02-03, 12:11:43:984 EST] 00000033 SystemErr R  at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commit(EntityTransactionImpl.java:161)
[2025-02-03, 12:11:43:985 EST] 00000033 SystemErr R  at com.xyz.Repository(AdminResource.java:946)
[2025-02-03, 12:11:43:985 EST] 00000033 SystemErr R  at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

添加@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)注解后功能恢复,但疑惑:使用RESOURCE_LOCAL时不应存在全局事务,如何彻底修复?

彻底修复方案

1. 确保数据源为非JTA配置

WebSphere Liberty中,即使persistence.xml指定non-jta-data-source,若数据源被配置为JTA类型,容器仍会自动关联全局事务。需修改服务器配置文件(如server.xml):

<dataSource id="jdbc/myAppDatasource" jndiName="jdbc/myAppDatasource" transactional="false">
    <!-- 驱动、URL、账号密码等其他配置 -->
</dataSource>

将transactional设为false,明确该数据源仅作为本地事务资源使用,不参与JTA全局事务。

2. 修正EntityManager获取逻辑

RESOURCE_LOCAL类型的EntityManager需手动创建,而非依赖容器注入。检查getEntityManager()方法:

  • 若当前是通过@PersistenceContext注入的EntityManager,容器可能会将其绑定到全局事务上下文,需改为手动创建:
private EntityManagerFactory emf;

private EntityManager getEntityManager() {
    if (emf == null) {
        emf = Persistence.createEntityManagerFactory("dbMyApp");
    }
    return emf.createEntityManager();
}
  • 补充资源清理:在方法末尾添加finally块,手动关闭EntityManager,避免资源泄漏:
finally {
    if (entityMgr != null && entityMgr.isOpen()) {
        entityMgr.close();
    }
}

3. 排查全局事务触发点

检查应用中是否存在自动开启全局事务的逻辑:

  • 控制器类或其父类是否被添加@Transactional(或EJB默认的@TransactionAttribute(REQUIRED))注解,导致方法被容器纳入全局事务管理。
  • 若使用JAX-RS,检查过滤器、拦截器或扩展点是否自动启动了全局事务。

4. 强制EclipseLink禁用全局事务关联

在persistence.xml的properties节点添加专属属性,强制EclipseLink不加入现有全局事务:

<property name="eclipselink.target-server" value="WebSphere_Liberty"/>
<property name="eclipselink.transaction.join-existing" value="false"/>

该配置会让EclipseLink忽略当前容器中的全局事务,严格使用RESOURCE_LOCAL的本地事务逻辑。

内容的提问来源于stack exchange,提问作者Hema Raj Narigannagari

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 11:54:52