我用:
考虑以下存储库:
public interface TestModelRepository extends JpaRepository<TestModel, Long> {
}
public interface TestModelRepository2 extends JpaRepository<TestModel2, Long> {
}
以及以下服务:
@Service
static class Svc {
@Autowired
private TestModelRepository modelRepository;
@Autowired
private TestModelRepository2 modelRepository2;
@Transactional
public void insertWithException() {
assertThat(TransactionAspectSupport.currentTransactionStatus()).isNotNull();
modelRepository.save(new TestModel("any"));
modelRepository2.save(new TestModel2("unique"));
modelRepository2.save(new TestModel2("unique"));
}
}
存储库2中的第二个保存会抛出DataIntegrityViolationException,因为提供的值不是唯一的。事务应回滚此方法中的所有内容,因为它使用@Transactional进行注释,但事实并非如此。
TestModel和TestModel2之一是持久的。实际上它们在每次save()调用之后都会持久存储到数据库中,因此即使@Transactional方法尚未完成(即我通过放置断点并登录到数据库来验证它),值也会插入到数据库中。在我看来,autocommit设置为true,我将其设置为false(在HikariCP配置中)。
这是我基于java的配置(片段):
@Bean
PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory);
return transactionManager;
}
@Bean
JpaVendorAdapter vendorAdapter() {
HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
adapter.setDatabase(Database.MYSQL);
adapter.setDatabasePlatform(MySQL5Dialect.class.getName());
return adapter;
}
LocalContainerEntityManagerFactoryBean entityManagerFactory = new LocalContainerEntityManagerFactoryBean();
entityManagerFactory.setDataSource(dataSource);
entityManagerFactory.setJpaVendorAdapter(vendorAdapter);
entityManagerFactory.setPackagesToScan(packagesToScan);
entityManagerFactory.setJpaProperties(properties);
主要问题:为什么交易不会回滚所有内容?
其他问题:
答案 0 :(得分:1)
您可能已在连接或db config中进行自动提交。我也注意到你正在使用mysql。确保您的架构和表格是InnoDB而不是MyISAM