我非常确定我的Spring Boot应用程序中没有应用事务,即使我正在使用@EnableTransactionManagement(mode=AdviceMode.ASPECTJ)
&在我的应用中有spring-aspects
。
@Configuration
public class DatastoreConfig{
@Bean
public DataSource dataSource(){ ///... }
@Bean
public JdbcTemplate jdbcTemplate(DataSource dataSource){
return new JdbcTemplate(dataSource);
}
@Bean
public String databaseSchema(){
return "mySchema";
}
@Bean
public OpenSessionInViewInterceptor openSessionInViewInterceptor(SessionFactory sessionFactory){
OpenSessionInViewInterceptor result = new OpenSessionInViewInterceptor();
result.setSessionFactory(sessionFactory);
return result;
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource, JpaVendorAdapter vendorAdapter){
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setJpaVendorAdapter(vendorAdapter);
factory.setPackagesToScan( Main.class.getPackage().getName() + ".model");
factory.setDataSource(dataSource);
factory.setJpaProperties(getJpaProperties());
factory.afterPropertiesSet();
return factory;
}
@Bean
public HibernateJpaVendorAdapter jpaVendorAdapter(){
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setGenerateDdl(false);
vendorAdapter.setDatabasePlatform(PostgreSQL9Dialect.class.getName());
return vendorAdapter;
}
@Bean
public SessionFactory sessionFactory(HibernateEntityManagerFactory emf){
SessionFactoryImpl sf = (SessionFactoryImpl) emf.getSessionFactory();
return sf;
}
private Properties getJpaProperties() {
Properties props = new Properties();
// props.put("hibernate.hbm2ddl.auto", "validate");
props.put("hibernate.ejb.naming_strategy", ImprovedNamingStrategy.class.getName());
props.put("hibernate.enable_lazy_load_no_trans", "true");
props.put("jadira.usertype.autoRegisterUserTypes", "true");
return props;
}
@Bean
public JpaTransactionManager transactionManager(EntityManagerFactory emf) throws PropertyVetoException {
JpaTransactionManager transactionManager = new JpaTransactionManager(emf);
transactionManager.setRollbackOnCommitFailure(true);
transactionManager.setDataSource(dataSource());
return transactionManager;
}
@Bean
public NamedParameterJdbcTemplate namedParameterJdbcTemplate(DataSource dataSource) {
return new NamedParameterJdbcTemplate(dataSource);
}
@Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
return new PersistenceExceptionTranslationPostProcessor();
}
}
@Configuration
@EnableTransactionManagement(mode = AdviceMode.ASPECTJ)
@ComponentScan
@EnableAsync
@EnableScheduling
@EnableEntityLinks
@EnableAspectJAutoProxy
@EnableApiResources(apiPrefix = "")
@EnableJpaRepositories(transactionManagerRef = "transactionManager")
@EnableHypermediaSupport(type = EnableHypermediaSupport.HypermediaType.HAL)
@EnableConfigurationProperties
@EnableAutoConfiguration
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
@EnableWebSocketMessageBroker
@Slf4j
public class Main extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(
SpringApplicationBuilder application) {
return application.sources(Main.class);
}
public static void main(String[] args) {
Object[] sources = {
Main.class,
TomcatConfig.class // include for embedded tomcat...
};
ConfigurableApplicationContext result = SpringApplication.run(sources, args);
}
}
我尝试验证的方法之一是运行
@Component
public class SomeService{
@Transactional
@Override
protected void tryItOut(){
// this is always false
boolean declarativeTransaction = TransactionSynchronizationManager.isActualTransactionActive();
// this throws an exception
TransactionStatus aspect = TransactionAspectSupport.currentTransactionStatus();
}
}
但是,如果我事先向transactionManager.getTransaction(new DefaultTransactionDefinition());
拨打电话,declarativeTransaction
为true
。
有关如何设置@Transactions /验证它们是否正常工作的任何建议?
答案 0 :(得分:0)
您的配置自相矛盾。
@EnableTransactionManagement(mode = AdviceMode.ASPECTJ)
表示您正在使用方面的加载时间或编译时编织。判断您的配置,您没有使用它。如果我必须判断你的配置你只是使用基本代理而不是编织。只需删除AdviceMode.ASPECTJ
它就可以了,你也不需要@EnableAspectJAutoProxy
因为申请交易与我们无关它(没有它可以工作)。
此外,您的配置基本上没有使用Spring Boot。你已经自动配置了很多弹簧启动已经为你做的事情。
Spring Boot已经为您配置了以下内容(仅指定@EnableAutoConfiguration
。
您可以移除大量配置并在application.properties
中添加一些属性。
如果您真的需要SessionFactory
而不是自己投票,我强烈建议您使用HibernateJpaSessionFactoryBean
。
我怀疑以下主类仍然有效(启用了事务)。
@Configuration
@ComponentScan
@EnableAsync
@EnableScheduling
@EnableAutoConfiguration
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
@EnableWebSocketMessageBroker
@Slf4j
public class Main extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(
SpringApplicationBuilder application) {
return application.sources(Main.class);
}
public static void main(String[] args) {
Object[] sources = {
Main.class,
TomcatConfig.class // include for embedded tomcat...
};
ConfigurableApplicationContext result = SpringApplication.run(sources, args);
}
}
使用此DatastoreConfig
类
@Configuration
public class DatastoreConfig{
@Bean
public FactoryBean<SessionFactory> sessionFactory(EntityManagerFactory emf){
HibernateJpaSessionFactoryBean jpaSessionFactoryBean = new HibernateJpaSessionFactoryBean();
jpaSessionFactoryBean.setEntityManagerFactory(emf);
return jpaSessionFactoryBean;
}
}
这是application.properties
spring.jpa.hibernate.naming-strategy=org.hibernate.cfg.ImprovedNamingStrategy
spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true
spring.jpa.properties.jadira.usertype.autoRegisterUserTypes=true
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQL9Dialect
您可能需要添加一些spring.datasource.
属性才能正确设置数据源。还要判断您使用的是OpenSessionInViewInterceptor
,而不是OpenEntityManagerInViewInterceptor
(或过滤器)。所以你甚至可以删除它。
不确定这是否是您的配置,但您可以删除/减少更多。我建议您查看Spring Boot参考指南,了解已经自动配置的内容。