3

我有一个对象列表。它们是 JPA“位置”实体。

List<Location> locations;

我有一个无状态的 EJB,它遍历列表并保留每个列表。

public void createLocations() {
    List<Locations> locations = getListOfJPAManagedLocationEntities(); // I'm leaving out the details of this because it has nothing to do with the issue

    for(Location location : locations) {
        em.persist(location);
    }
}

代码工作正常。我没有任何问题。但是,问题是:我希望这是一个全有或全无的交易。目前,每次通过 for 循环,persist() 方法都会在数据库中插入一个新行。假设我有 100 个位置对象,而第 54 个对象有问题并引发异常。将有 53 条记录插入到数据库中。我想要的是:他们都必须先成功,然后才能成功。

我正在使用最新最好的 Java EE6、EJB 3.x 和 JPA 2 版本。我的 persistence.xml 使用 JTA。

<persistence-unit name="myPersistenceUnit" transaction-type="JTA">

我喜欢有 JTA。我不想停止使用 JTA。90% 的时间 JTA 完全按照我的意愿去做。但在这种情况下,我似乎没有。

我对 JTA 的理解一定是不准确的,因为我一直认为 EJB 方法的开始和结束标记了 JTA 事务的边界(假设只有一种方法在起作用,如上所示)。按照我的逻辑,在 for 循环完成并且方法返回之前,事务不会结束,然后记录就会被持久化。

我正在使用 SqlServer 2008 的 JTDS 驱动程序。也许数据库不想在不立即提交记录的情况下插入记录。实体 id 定义如下:

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)

我检查了规范,在 JTA 环境中调用各种“UserTransaction”或“getTransaction()”方法是不合适的。

那么我能做什么呢?谢谢。

4

3 回答 3

0

如果您使用 JTA 和容器管理的事务,则会话 EJB 方法调用的默认行为是在事务中运行(就像用@TransactionAttribute(TransactionAttributeType.REQUIRED).发生在第 54 行,所有先前插入的行都将被回滚。您可以通过在循环中的某个点向自己抛出异常来继续测试它。请注意,如果您抛出由您的方法声明的检查异常,您可以指定当异常发生时,容器应该做。你需要用 注释异常类@ApplicationException (rollback=true)

于 2013-02-20T21:42:53.307 回答
0

如果循环时有重复的条目,那么它将继续没有问题,当编译器em.flush();在循环后到达这一行时,它将抛出异常并回滚事务。

于 2013-03-19T12:20:35.913 回答
0

我正在使用 JBoss。将您的数据源设置在您的standalone.xml 或 domain.xml 中 <datasource jta="true" ...> 看起来很明显,但我显然很久以前就设置错了并且忘记了它。

于 2015-11-30T21:19:36.787 回答