admin管理员组

文章数量:1293620

I came across an old project using JPA with MSSQL server running on Websphere Liberty. In the persistence.xml file there is a persistent unit with the following declaration:

<persistence version="2.0" xmlns="; xmlns:xsi="; xsi:schemaLocation=" .xsd">
  <persistence-unit name="dbMyApp" transaction-type="RESOURCE_LOCAL">
    <provider>.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
{
    ry {
        
            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()mit();
                
        }
        catch (javax.persistence.EntityExistsException e)
        {
            return Response.status(Response.Status.INERNAL_SERVER_ERROR).entity(new ErrorResponse(e.getMessage())).build();
        }
}

In the case that we are using RESOURCE_LOCAL transactions and there is code to manually manage the transactions scattered throughout the whole application. Whenever I try to create Repository, it fails with below error.

[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): .eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLException: DSRA9350E: Operation Connectionmit is not allowed during a global transaction.
Error Code: 0
[2025-02-03, 12:11:43:984 EST] 00000033 SystemErr R  at .eclipse.persistence.internal.jpa.transaction.EntityTransactionImplmit(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)

I tried annotating the method with TransactionAttributeType.NOT_SUPPORTED, postRepository(Repository repository) is working as expected. It actually suspend the global transaction. Once user transaction completes(begin, commit) global transaction is resumed. But transaction type RESOURCE_LOCAL is used, I think global transaction should not be exists. How to fix this issue

I came across an old project using JPA with MSSQL server running on Websphere Liberty. In the persistence.xml file there is a persistent unit with the following declaration:

<persistence version="2.0" xmlns="http://java.sun/xml/ns/persistence" xmlns:xsi="http://www.w3./2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun/xml/ns/persistence http://java.sun/xml/ns/persistence/persistence_2_0.xsd">
  <persistence-unit name="dbMyApp" transaction-type="RESOURCE_LOCAL">
    <provider>.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
{
    ry {
        
            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()mit();
                
        }
        catch (javax.persistence.EntityExistsException e)
        {
            return Response.status(Response.Status.INERNAL_SERVER_ERROR).entity(new ErrorResponse(e.getMessage())).build();
        }
}

In the case that we are using RESOURCE_LOCAL transactions and there is code to manually manage the transactions scattered throughout the whole application. Whenever I try to create Repository, it fails with below error.

[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): .eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLException: DSRA9350E: Operation Connectionmit is not allowed during a global transaction.
Error Code: 0
[2025-02-03, 12:11:43:984 EST] 00000033 SystemErr R  at .eclipse.persistence.internal.jpa.transaction.EntityTransactionImplmit(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)

I tried annotating the method with TransactionAttributeType.NOT_SUPPORTED, postRepository(Repository repository) is working as expected. It actually suspend the global transaction. Once user transaction completes(begin, commit) global transaction is resumed. But transaction type RESOURCE_LOCAL is used, I think global transaction should not be exists. How to fix this issue

Share Improve this question edited Feb 25 at 23:56 Gas 18.1k4 gold badges47 silver badges99 bronze badges asked Feb 12 at 15:54 Hema Raj NarigannagariHema Raj Narigannagari 1 3
  • This looks like a dev level project - it is using property "eclipselink.ddl-generation" value="create-or-extend-tables" which isn't recommended for production - so is this working somewhere? This persistence unit is configured to use a non-JTA datasource, so shouldn't be participating in any JTA transactions at all unless it has been misconfigured at the server level. Check how you've configured this datasource in your server. Fixing the issue depends on what you want to do - do you want the methods to participate in global/server managed transactions, or continue to use resource-local? – Chris Commented Feb 12 at 17:10
  • Could you please format your error trace? – PatPanda Commented Feb 13 at 2:14
  • How does your getEntityManager() method look like? As it looks like you still participate in global transaction.... – Gas Commented Feb 26 at 0:00
Add a comment  | 

1 Answer 1

Reset to default 0

In WebSphere Liberty’s server.xml, make sure your data source is set to non-transactional:

<dataSource id="myAppDatasource" 
            jndiName="jdbc/myAppDatasource" 
            transactional="false">
    <jdbcDriver ... /> <!-- Add driver details here -->
    <properties ... /> <!-- Add properties if needed -->
</dataSource>

Refer this document : https://openliberty.io/docs/latest/transaction-service.html

本文标签: