【问题标题】:How can I isolate entity validation in order to prevent transaction rollback of a whole bulk (persist) transaction?如何隔离实体验证以防止整个批量(持久)事务的事务回滚?
【发布时间】:2014-07-01 23:27:59
【问题描述】:

我有带有验证注释的实体,例如@NotNull。我不知道如何防止容器管理的事务在批量持久操作中出现 ConstraintViolationException 的情况下回滚,例如:

public void persistAll(List<TheEntity> entities) throws Exception{

for(TheEntity ent : entities){

em.persist(ent);

}

}

将持久化操作包装在 try-catch 中并不能解决问题,因为即使捕获了约束异常,事务也会被标记为回滚(不会保留任何其他“已验证”实体)。我可以隔离每个实体的事务以保持持久,但我认为这会对性能产生很大影响(对此不确定,我正在使用 eclipselink 和批处理 JDBC 优化)。

我知道 ContraintValidationException 的行为符合 JPA 规范的要求(标记回滚),但我不确定我是否了解 eclipselink 批量优化的工作原理(批量操作是否需要在单笔交易?)。

感谢您的关注。

问候。

编辑:Welp,eclipelink 文档指出“批量写入可以通过在单个事务中而不是单独向数据库发送 INSERT、UPDATE 和 DELETE 语句组来提高数据库性能。”,所以是的,它需要在单个事务中完成。

编辑:我还可以从上下文中注入一个约束验证器并禁用 persistence.xml 上的 JPA 验证器,这样我就可以在 JPA PrePersist 操作之前验证实体列表。但是,这将影响不需要对其进行批量操作但仍需要验证的其他实体。啊!差不多了。

【问题讨论】:

  • 只是为了确定,例如,您需要处理 4 个条目,而第三个条目抛出异常,您希望前 2 个更改提交并丢弃第 3 个和第 4 个?
  • 我只想丢弃触发约束异常的实体。其余的必须坚持。我还发现我可以使用 flush 方法,但又一次不确定性能影响。
  • 老实说,我对 JPA 了解不多,我只是来这里学习并可能贡献一点。你说 try catch 不起作用....你确定吗?如果你包围整个操作,那么它可能不起作用,那么只包围抛出异常的行(在循环内)呢?这样,您可能会选择忽略异常并继续进行您的交易。您还可以在 catch 中添加某种变量/缓冲区来记录循环期间发生的所有异常,并稍后针对这些异常执行您的操作。
  • 好吧,规范规定如果发生 ContraintValidationException,事务将被标记为回滚。所以一旦火了,就什么也做不了。是的,我可以抓住它,但在那个时候没用。
  • 这可能是一个无用的评论,但显然在这种特定情况下,您不想要持久性,而不是为什么使用 JPA :D 。好的,除了无用的评论,虽然这可能是一种效率较低的做事方式,也许你可以尝试像我建议的那样,但在捕获部分记录哪个实体有问题(通过列表索引?)然后一切都是回滚,如果检测到错误缓冲区不为空,从列表中删除实体并将列表放回方法中并再次运行?不确定你的表现。

标签: java jpa eclipselink java-ee-7


【解决方案1】:

您可以进行手动验证并跳过无效的实体,如下所示:

// in the class inject validator
@Resource
Validator validator;
...

for(TheEntity ent : entities){
     if( validator.validate(ent).size() == 0) {
         // valid - persist
         em.persist(ent);       
     } else {
        // invalid - skip
    }
}

【讨论】:

  • 确实如此,正如我在 5 月 14 日的最后一次编辑中提到的那样。但是,为了值得这样做,必须在 persistence.xml 中禁用默认的 JPA 验证器,如果没有,验证步骤将执行两次(影响性能)。感谢您的关注!
猜你喜欢
  • 2014-03-07
  • 2010-12-14
  • 1970-01-01
  • 2014-07-17
  • 2014-11-12
  • 1970-01-01
  • 1970-01-01
  • 2020-04-11
  • 1970-01-01
相关资源
最近更新 更多