gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-01 17:09:14 25 4
gpt4 key购买 nike

为了简化我的场景,我将给出以下示例:

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

在标有 @Transactional 注释的 java 方法内,我想使用纯 hibernate 执行数千条记录的批量插入。批量插入是通过一个单独的方法执行的,该方法由带有 @Transactional 的 main 方法调用。我就是这样做的:

@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 block 包围 for 循环并抛出已检查的异常并使用 @Transactional 的 rollbackFor 属性?我不确定批处理失败期间引发的异常是否已检查或未检查。

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

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

最佳答案

你是对的。默认情况下,@Transactional只会回滚 RuntimeExceptionError但不适用于已检查的异常。这意味着如果您还想回滚已检查的异常,则必须捕获所有已检查的异常并将其重新抛出为 RuntimeException或者简单地使用rollbackFor设置在@Transactional .

I'm not sure if the exceptions thrown during batch failure are checked or unchecked.

java编译器会帮助检查它。如果某些内部方法抛出检查异常,则要求您必须处理它,但您既不能捕获它,也不能在方法声明中指定抛出此检查异常。如果不这样做,代码将无法编译。

这意味着如果您的代码可以编译,则内部方法不会抛出已检查的异常,您只需坚持当前设置即可。另一方面,如果内部方法抛出一些已检查的异常,您可以选择捕获它并重新抛出它,如RuntimeException。 :

@Transactional
public void doSomeStuff() {
try{

}catch(Exception ex){
throw new RuntimeException("something goes wrong.." ,ex);
}
}

或配置rollbackFor

@Transactional(rollbackFor={Exception.class})
public void doSomeStuff() throws Exception{

}

另外,请注意 session.flush()与提交事务不同,因此您的代码不会为每个批处理提交。相反,事务将在标有 @Transactional 的方法成功返回后提交,在您的情况下返回 doSomeStuff()当所有记录都插入时。

flush()的要点用于后续session.clear()它会从 session 中清除内存,这样如果插入大量记录,就不会导致 JVM 内存不足。

关于java - 如何在Spring Boot应用程序中的@Transactional方法中使用纯Hibernate保证原子批量插入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61440270/

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