【问题标题】:No active transaction in EJB @Schedule methodEJB @Schedule 方法中没有活动事务
【发布时间】:2016-05-16 22:58:04
【问题描述】:

我有一个带有@Schedule 标记方法的EJB,它将实体持久保存到数据库中。在这个方法中,当我在persist() 之后调用EntityManager.flush() 时,我得到javax.persistence.TransactionRequiredException: No transaction is currently active

AFAIK 所有 EJB 方法都是事务性的,但即使我另外使用 @TransactionAttribute(REQUIRED) 标记该方法,我也会收到此错误。

当我通过 EntityTransaction.begin() 和 commit() 手动管理事务时,一切正常。

我在 JDK 8u74、EclipseLink 2.6.0 上使用 Wildfly 10.0 Final。

这是我的 persistence.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" version="2.1">    
    <persistence-unit name="mainPU" transaction-type="JTA">
        <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
        <jta-data-source>java:/datasources/ExampleDS</jta-data-source>
        <class>com.example.MyEntity</class>
    </persistence-unit>    
</persistence>

MyEJB.java:

package com.example;

import javax.ejb.*;
import javax.ejb.Timer;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

@Startup
@DependsOn("AppUtils")
@Singleton
public class MyEJB {
    @PersistenceContext(unitName = "mainPU")
    private EntityManager em;

    @Schedule(hour = "*", minute = "*", second = "*/20", info = "", persistent = false)
    private void doStuff(Timer timer) {
        MyEntity entity = new MyEntity("Test" + Math.random(), "Test value");
        em.merge(entity);
        em.flush();
    }
}

【问题讨论】:

  • doStuff 真的是私有方法吗?如果是这样,它不太可能被正确调用,如果有的话。
  • 是的,doStuff 是一个私有方法,它通过计时器调用就好了。
  • 你让我仔细检查了规范,你是对的:“超时回调方法可以具有公共、私有、受保护或包级别的访问权限。不得声明超时回调方法作为最终的或静态的。”这适用于 EJB 3.1 和 3.2。 - 谢谢!
  • 这可能是与 Eclipse JPA 的集成错误。如果您注释掉 ... 以便使用默认(Hibernate)JPA 实现,它是否有效?

标签: jpa jakarta-ee ejb jta


【解决方案1】:

当您使用 JTA 时,它会提交并将更改刷新到数据库中并关闭当前事务。所以,当你做em.flush()时,事务已经关闭了。

【讨论】:

  • 不行,事务只在方法返回时提交,而不是在调用em.merge时提交,否则异常将无法回滚同一方法内的事务
猜你喜欢
  • 1970-01-01
  • 2015-08-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-06
  • 2017-05-14
相关资源
最近更新 更多