【发布时间】:2017-12-15 18:48:02
【问题描述】:
我们为 JPA 配置了 Spring Data。服务事务方法不会因错误(例如 DB ConstraintViolationException)而回滚。
我能找到的最接近的是这个 (Transaction not rolling back) Spring-data, JTA, JPA, Wildfly10 但是我们没有任何 XML 配置,我们所有的配置都是基于 Java 的。
基本上,服务方法看起来像这样:没有错误被捕获,一切都被抛出。
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class, readOnly = false)
public void insertEvent() throws Exception {
// Part 1
EventsT event = new EventsT();
// populate it..
eventsDAO.save(event);
// Part 2 - ERROR HAPPENS HERE (Constraint Violation Exception)
AnswersT answer = new AnswersT();
// populate it..
answersDAO.save(answer);
}
第 2 部分失败。但是在错误并返回之后,我看到事件(第 1 部分)仍然填充在数据库中。
我们还尝试了@Transactional 的各种组合,但没有任何效果:
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class, readOnly = false)
@Transactional(readOnly = false)
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = ConstraintViolationException.class, readOnly = false)
Spring Data CRUD DAO 接口:
@Repository
public interface EventsDAO extends JpaRepository<EventsT, Integer> {
}
@Repository
public interface AnswersDAO extends JpaRepository<AnswersT, Integer> {
}
JpaConfig:
@Configuration
@EnableJpaRepositories(basePackages = "com.myapp.dao")
@PropertySource({ "file:${conf.dir}/myapp/db-connection.properties" })
public class JpaConfig {
@Value("${jdbc.datasource}")
private String dataSourceName;
@Bean
public Map<String, Object> jpaProperties() {
Map<String, Object> props = new HashMap<String, Object>();
props.put("hibernate.dialect", PostgreSQL95Dialect.class.getName());
//props.put("hibernate.cache.provider_class", HashtableCacheProvider.class.getName());
return props;
}
@Bean
public JpaVendorAdapter jpaVendorAdapter() {
HibernateJpaVendorAdapter hibernateJpaVendorAdapter = new HibernateJpaVendorAdapter();
hibernateJpaVendorAdapter.setShowSql(true);
hibernateJpaVendorAdapter.setGenerateDdl(true);
hibernateJpaVendorAdapter.setDatabase(Database.POSTGRESQL);
return hibernateJpaVendorAdapter;
}
@Bean
public PlatformTransactionManager transactionManager() throws NamingException {
return new JpaTransactionManager( entityManagerFactory().getObject() );
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() throws NamingException {
LocalContainerEntityManagerFactoryBean lef = new LocalContainerEntityManagerFactoryBean();
lef.setDataSource(dataSource());
lef.setJpaPropertyMap(this.jpaProperties());
lef.setJpaVendorAdapter(this.jpaVendorAdapter());
lef.setPackagesToScan("com.myapp.domain", "com.myapp.dao");
return lef;
}
@Bean
public DataSource dataSource() throws NamingException {
return (DataSource) new JndiTemplate().lookup(dataSourceName);
}
}
Spring Data 和 JPA 是否存在任何事务回滚问题?
【问题讨论】:
-
为了澄清,您使用的是
org.springframework.transaction.annotation.Transactional还是javax.transaction.Transactional?而insertEvent()是过程中第一个注解为Transactional的方法? -
事务注解是
org.springframework.transaction.annotation.Transactional。是的,insertEvent 方法使用@Transactional 注释,如上所示。 -
什么是数据库?案例 MySQL:没有 engine=InnoDB 就不可能回滚
-
PostgreSQL。事实上,即使我尝试删除,Spring Data 也会抱怨没有事务:javax.persistence.TransactionRequiredException: Executing an update/delete query。所以没有找到交易,即使我注释了它!
标签: spring jpa spring-data spring-data-jpa