gpt4 book ai didi

jpa-2.0 - JPA 与 JTA 如何在一个事务中保留多个实体

转载 作者:行者123 更新时间:2023-12-04 19:38:44 26 4
gpt4 key购买 nike

我有一个对象列表。它们是 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()”方法是不合适的。

那我该怎么办呢?谢谢。

最佳答案

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

关于jpa-2.0 - JPA 与 JTA 如何在一个事务中保留多个实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14990226/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com