不能回滚Spring事务
在一个项目中,我需要将一个CSV文件导入数据库,在出现任何问题时这次操作必须回滚。
一个服务调用一个辅助工具,从文件中读取数据并把它们放入一个 List 中,然后它调用一个继承自 CrudRepository 的仓储,以 saveAll() 的方式持久化数据。我在仓储的 saveAll() 上方以及服务的导入方法上添加了 @Transactional 注解。
我的问题是,当运行我的代码时(导入一个缺少字段的CSV文件),会抛出一个 ConstraintViolationException 异常,但回滚并没有执行,数据库中已经持久化的数据仍然留存。
我读到回滚只对未检查异常起作用,所以我把代码中的任何 try/catch 或 throw 移除了,但问题仍然存在。
我也尝试使用 rollbackFor 属性,但没有效果。
作为Spring的新手,我可能会有些错误,但我想不出到底哪里错了。你能帮我定位问题吗?
先行致谢,以下是我的代码:
ReferentielRIService.java
package com.orange.fafsi.api.referentielRi.service;
import com.orange.fafsi.api.referentielRi.helper.ReferentielRiCsvHelper;
import com.orange.fafsi.api.referentielRi.model.ReferentielRi;
import com.orange.fafsi.api.referentielRi.repository.ReferentielRiRepository;
import com.orange.fafsi.api.state_machine.Cursor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.io.File;
import java.util.List;
import java.util.logging.Logger;
@Service
public class ReferentielRiService {
private static final Logger logger = Logger.getLogger("import_ref_ri");
@Autowired
private ReferentielRiRepository repository;
@Autowired
private ReferentielRiCsvHelper csvHelper;
@Autowired
private Cursor cursor;
@Transactional()
public void importAll(File file) {
this.cursor.next();
List<ReferentielRi> list = this.csvHelper.csvToList(file, false, ',');
this.repository.saveAll(list);
}
}
ReferentielRIRepository.java
package com.orange.fafsi.api.referentielRi.repository;
import com.orange.fafsi.api.referentielRi.model.ReferentielRi;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
@Repository
@Transactional()
public interface ReferentielRiRepository extends CrudRepository<ReferentielRi, Long> {
@Transactional()
@Override
<S extends ReferentielRi> Iterable<S> saveAll(Iterable<S> entities);
}
解决方案
你的问题不是你的代码,而是你的表类型。MyISAM表不支持事务,每条语句执行时都像一个独立的自动提交事务。
如果你想要完全可控的事务,需要把表改为INNODB类型。
下面是来自MySQL文档的一个有用链接:17.6.1.5将 MyISAM表转换为InnoDB
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。