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>
排查方向
事务注解有效性校验
- 确认
@Transactional为Java EE规范注解(javax.transaction.Transactional或jakarta.transaction.Transactional),而非第三方框架注解,WildFly仅对规范注解提供事务拦截支持。 - 若
readInputFolder属于DocumentImportService(@Stateless),需确认方法为public(已满足),同时检查是否存在方法被final修饰(会导致拦截器失效)。
- 确认
EJB内部调用的事务拦截问题
- 检查
doImport调用readInputFolder的方式:若为类内部this.readInputFolder()调用,EJB代理的事务拦截器不会生效,导致readInputFolder的@Transactional无效。解决方式:将readInputFolder迁移至独立EJB,或通过注入自身的代理对象调用该方法。
- 检查
CDI Bean的事务支持
StartController为@ApplicationScopedCDI Bean,默认情况下WildFly不会为非EJB的CDI Bean处理@Transactional注解。需将StartController改为@Stateless/@SingletonEJB,或在WildFly中开启CDI事务拦截器配置。
EntityManager上下文与事务关联
- 显式指定
@PersistenceContext(type = PersistenceContextType.TRANSACTION)(默认值,但可排除配置歧义),确保EntityManager仅在事务上下文内关联。 - 排查代码中是否存在手动调用
em.close()的情况,避免EntityManager提前脱离事务。
- 显式指定
数据源配置验证
- 检查WildFly配置文件(
standalone.xml/domain.xml)中java:jboss/datasources/Aktenimport的jta属性是否为true,同时确认数据源可正常连接数据库,排除底层连接问题导致事务无法初始化。
- 检查WildFly配置文件(
事务状态与日志排查
- 在
readInputFolder方法开头添加日志,通过UserTransaction获取当前事务状态,确认执行时是否存在事务。 - 查看WildFly服务器日志,排查是否有事务管理器初始化失败、数据源事务关联错误等警告信息。
- 在
内容的提问来源于stack exchange,提问作者maio290
相关产品推荐
相关产品推荐

