如何在Spring Boot应用程序的@Transactional方法中使用纯Hibernate保证原子批处理插入]]

问题描述 投票:0回答:1

为了简化我的情况,我将举以下示例:

我正在使用带有spring.jpa.properties.hibernate.order_inserts = true属性的Spring Boot应用程序。

在标有@Transactional批注的java方法中,我想使用纯休眠模式批量插入几千条记录。批处理插入是通过单独的方法执行的,该方法由main方法使用@Transactional调用。我是那样做的:

@Transactional
public void doSomeStuff() {
......
insertRecords(records, session);
......
}


private void insertRecords(final List<Record> records, final Session session) {
  int counter = 0;
  int batchSize = 50;
  for(Record r: records){
    session.save(r);

    counter ++;

    if(counter > 0 && counter % batchSize == 0){
       session.flush(); 
       session.clear();
    }

    }
}     

问题是我希望该操作是原子操作,并且如果其中一个批处理插入,将使所有操作都无法回滚。我知道@Transactional注释将保证为RunTimeException或Error自动回滚。这是否意味着如果批处理之一失败,@ Transactional将覆盖回滚,或者我应该用try / catch块将for循环括起来,并抛出一个已检查的异常,并使用@Transactional的rollbackFor属性?我不确定批处理失败期间引发的异常是否已选中。

另一个重要的问题是,在这种情况下,如果成功插入,休眠状态会自动提交每个批处理吗?这意味着如果一批失败,我将无法回滚已经提交的一次,这破坏了原子性。

此外,我不想手动管理提交,而是想处理Spring提供的事务性上下文。

为了简化我的场景,我将举一个下面的例子:我正在使用一个带有spring.jpa.properties.hibernate.order_inserts = true属性的Spring Boot应用程序。在标有@ ...

java hibernate spring-boot atomic rollback
1个回答
0
投票

你是对的。默认情况下,@Transactional仅针对RuntimeExceptionError进行回滚,而不针对已检查的异常进行回滚。这意味着,如果您还想回滚已检查的异常,则必须捕获所有已检查的异常,然后将其重新抛出为RuntimeException或直接使用rollbackFor中的@Transactional设置。

© www.soinside.com 2019 - 2024. All rights reserved.