spring-mybatis - Springboot / MyBatis 批量插入不会在错误时回滚(甚至在强制时)
问题描述
我试图让事务在 SpringBoot + MyBatis 中工作,但无论我尝试什么,它都不会回滚。我也已经添加@Transactional
到该方法中。我错过了什么?我做错了吗?flushStatements()
并clearCache()
承诺?文档SqlSession.commit()
说“flushStatements and commit”,所以它似乎不应该。
try (SqlSession sqlSession = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH)) {
MyMapper1 mapper1 = sqlSession.getMapper(MyMapper1.class);
for (int i = 0; i < results1.size(); i++) {
mapper1.insert(results1.get(i));
if ((i != 0 && i % BATCH_SIZE == 0) || i == results1.size()- 1) {
sqlSession.flushStatements();
sqlSession.clearCache();
}
}
sqlSession.rollback(true); // didn't work
int forceError = 100 / 0; // so I tried this, also didn't work
MyMapper2 mapper2 = sqlSession.getMapper(MyMapper2.class);
for (int i = 0; i < results2.size(); i++) {
count = count + mapper2.insert(results2.get(i));
if ((i != 0 && i % BATCH_SIZE == 0) || i == results2.size()- 1) {
sqlSession.flushStatements();
sqlSession.clearCache();
}
}
}
我的主要应用:
@SpringBootApplication
@EnableTransactionManagement
public class MyApplication extends SpringBootServletInitializer implements CommandLineRunner {
@Autowired
MyService service;
}
和服务等级:
@Service
public class MyService {
public void doStuff() {
insert();
}
@Transactional
private void insert() {
解决方案
确保您已@EnableTransactionManagement
在 SpringBootApplication 类或任何类上添加注释@Configuration
。
更新(因为提供了额外的代码):
这应该工作
@Service
public class MyService {
@Transactional // assuming this method is invoked from external code
public void doStuff() {
insert();
}
private void insert() { ... }
}
MyService
如果从另一个注入的类调用( @Autowired
)。
@Transactional
放在非公共方法上是没用的,甚至不会发生事务包装。Spring 的调用需要通过代理才能使其工作。因此,需要从另一个 bean 调用该方法。
在此处导航以获取有关 Spring 代理的更多详细信息
https://www.marcobehler.com/guides/spring-transaction-management-transactional-in-depth
https://spring.io/blog/2012/05/23/transactions-caching-and-aop-understanding-proxy-usage-in-spring