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

WildFly 25中Java EE应用@Transactional与@Stateless无事务异常求助

排查WildFly 25下Java EE应用的无事务异常

在WildFly 25上运行纯Java EE应用时,遇到WFLYJPA0060无事务异常,此前同类配置在多个客户环境中正常工作,已确认组件注入、@Stateless注解、@Transactional标注均符合规范,且数据源已配置JTA=true。


相关代码片段

Repository类

@Stateless
public class DocumentImportLogRepository{
    
    @PersistenceContext(unitName = "AktenimportPU")
    EntityManager em;
    
    public <T> Object find(Class<T> entityClass, Object primaryKey)
    {
        return em.find(entityClass, primaryKey);
    }
    
    public void persist(Object object)
    {
        em.persist(object);
    }
    
    public void forcePersist(Object object)
    {
        em.persist(object);
        em.flush();
    }
    
    public void merge(Object object)
    {
        em.merge(object);
    }
    
    public void forceMerge(Object object)
    {
        em.merge(object);
        em.flush();
    }

    public void remove(Object object)
    {
        em.remove(object);
    }   
}

Service类(Repository注入部分)

@Stateless
public class DocumentImportService 

[...]
    @Inject
    DocumentImportLogRepository importLogRepo;

Service核心调用方法

@Transactional
public void doImport()
{
    [...]
    readInputFolder(Config.DOCUMENT_IMPORT_FOLDER);
    prepareImport(importLogRepo.getByState(State.PARSED), getPersonalakten());
    performArchive(importLogRepo.getByState(State.PREPARED));
    performArchiveMove(importLogRepo.getByState(State.ARCHIVED));
    [...]
}

触发调用的Controller

@Named("StartController")
@ApplicationScoped
public class StartController implements Serializable {

    
    @Inject
    private transient DocumentImportService importService;
    
    [...]
    
    @Transactional
    @TransactionTimeout(value=120, unit = TimeUnit.MINUTES)
    public void performTask(Task task)
    {
        [...]

            switch(task)
            {
                case Personalaktenimport:
                    importService.doImport();
                    break;
            }

        [...]
            
    }
}

报错的具体方法

@Transactional
public void readInputFolder(Path inputFolder) throws IOException
{
    [...] importLogRepo.forcePersist(entry); [...]
}

抛出的异常

javax.ejb.EJBTransactionRolledbackException: WFLYJPA0060: Transaction is required to perform this operation (either use a transaction or extended persistence context

persistence.xml配置

<persistence 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"
             version="2.0">
   <persistence-unit name="AktenimportPU">
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
      <jta-data-source>java:jboss/datasources/Aktenimport</jta-data-source>
      <properties>
         <property name="hibernate.hbm2ddl.auto" value="none"/>
         <property name="hibernate.dialect" value="org.hibernate.dialect.SQLServerDialect"/>
         <property name="hibernate.jdbc.time_zone" value="Europe/Berlin"/>
         
      </properties>
   </persistence-unit>
      
</persistence>

排查方向

  1. 事务注解有效性校验

    • 确认@Transactional为Java EE规范注解(javax.transaction.Transactional或jakarta.transaction.Transactional),而非第三方框架注解,WildFly仅对规范注解提供事务拦截支持。
    • 若readInputFolder属于DocumentImportService(@Stateless),需确认方法为public(已满足),同时检查是否存在方法被final修饰(会导致拦截器失效)。
  2. EJB内部调用的事务拦截问题

    • 检查doImport调用readInputFolder的方式:若为类内部this.readInputFolder()调用,EJB代理的事务拦截器不会生效,导致readInputFolder的@Transactional无效。解决方式:将readInputFolder迁移至独立EJB,或通过注入自身的代理对象调用该方法。
  3. CDI Bean的事务支持

    • StartController为@ApplicationScoped CDI Bean,默认情况下WildFly不会为非EJB的CDI Bean处理@Transactional注解。需将StartController改为@Stateless/@Singleton EJB,或在WildFly中开启CDI事务拦截器配置。
  4. EntityManager上下文与事务关联

    • 显式指定@PersistenceContext(type = PersistenceContextType.TRANSACTION)(默认值,但可排除配置歧义),确保EntityManager仅在事务上下文内关联。
    • 排查代码中是否存在手动调用em.close()的情况,避免EntityManager提前脱离事务。
  5. 数据源配置验证

    • 检查WildFly配置文件(standalone.xml/domain.xml)中java:jboss/datasources/Aktenimport的jta属性是否为true,同时确认数据源可正常连接数据库,排除底层连接问题导致事务无法初始化。
  6. 事务状态与日志排查

    • 在readInputFolder方法开头添加日志,通过UserTransaction获取当前事务状态,确认执行时是否存在事务。
    • 查看WildFly服务器日志,排查是否有事务管理器初始化失败、数据源事务关联错误等警告信息。

内容的提问来源于stack exchange,提问作者maio290

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 18:50:26