为了简化我的情况,我将举以下示例:
我正在使用带有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应用程序。在标有@ ...
你是对的。默认情况下,@Transactional
仅针对RuntimeException
和Error
进行回滚,而不针对已检查的异常进行回滚。这意味着,如果您还想回滚已检查的异常,则必须捕获所有已检查的异常,然后将其重新抛出为RuntimeException
或直接使用rollbackFor
中的@Transactional
设置。