Java 如何验证Spring+AspecJ事务?
我非常确定Spring启动应用程序中没有应用事务,即使我在应用程序中使用@EnableTransactionManagementmode=AdviceMode.ASPECTJ&have Spring aspects 配置 主类 试图核实 我试图验证的方法之一是运行Java 如何验证Spring+AspecJ事务?,java,spring,spring-boot,spring-transactions,Java,Spring,Spring Boot,Spring Transactions,我非常确定Spring启动应用程序中没有应用事务,即使我在应用程序中使用@EnableTransactionManagementmode=AdviceMode.ASPECTJ&have Spring aspects 配置 主类 试图核实 我试图验证的方法之一是运行 @Component public class SomeService{ @Transactional @Override protected void tryItOut(){ // t
@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.getTransactionnew DefaultTransactionDefinition的调用;在此之前,declarativeTransaction为true
关于如何设置@Transactions/验证它们是否正常工作,有什么建议吗 您的配置自相矛盾
@EnableTransactionManagement(mode = AdviceMode.ASPECTJ)
意味着您正在使用方面的加载时或编译时编织。根据您的配置判断,您没有使用它。如果我必须判断您的配置,您只是在使用基本代理而不是编织。只需删除AdviceMode.ASPECTJ,它就会工作,您也不需要@EnableSpectJautoproxy,因为应用事务与此无关,它可以在没有它的情况下工作
另外,您的配置在基本上不使用Spring引导方面做了很多工作。您已经配置了SpringBoot已经为您自动、手动完成的许多事情
仅通过指定@EnableAutoConfiguration,SpringBoot已经为您配置了以下内容
实体管理工厂
数据来源
使用
事务设置
OpenEntityManager视图
弹簧腹板插座
超媒体支持
Spring数据JPA设置
您可以删除大量配置,并将一些属性放在application.properties中
如果您真的需要SessionFactory而不是自己进行转换,我强烈建议您使用HibernateJPAsionFactoryBean
我怀疑下面的主类仍然在启用事务的情况下工作
@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类
您可能需要添加一些spring.datasource。属性来正确设置数据源。另外,从您有一个OpenSessionInviewWinterCeptor这一事实来看,您使用了它而不是OpenEntityManagerViewInterceptor过滤器。所以你甚至可以移除它
不确定这是否是您的全部配置,但您可能可以删除/修剪更多。我建议看一看Spring Boot参考指南,了解一下已经自动配置的功能。我不相信您的代码。特别是,您正在重写一个代码不可能重写的方法。我怀疑有自我呼叫问题;发布真实代码。为了简洁,我删减了内容。tryItOut实际上保存了一些血淋淋/无关的信息,这些信息是我为了尝试和调试而分割的。即使这是一个自调用问题,事务边界也是在控制器中的一个层上设置的,因此在这一点上,无论tryItOut的边界如何,我们都应该有一个事务。啊,运行时类路径上有aspectjrt吗?是的,都与Maven捆绑在一起。此外,@Aspect建议也非常有效。只是不是TransactionModeAspectJ意味着您使用方面来编织加载或编译时,但并不意味着您正在使用代理。但是,添加@enableAspectProxy使用代理。那么应该使用什么呢。另外,为了不使用Spring Boot,你似乎做了很多工作。谢谢你的详细帖子。我必须多读一些关于AspectJ设置的书,因为我还没有完全掌握它。所以,我的部分问题是,我不想使用代理,因为在某些情况下,我正在注入具体的类,并获得可怕的无法将$Proxy192强制转换为FooService。我以为AspectJ事务所需要做的只是这些配置,但听起来我需要:为编译或运行时插入指令?是这样吗?您还使用了@enablesync,它还创建了一个代理,因此您还必须将其切换到AspectJ。您确实应该添加编译时或加载时编织,或者找到一种方法来解决需要具体类的问题,因为您应该对接口进行编程。
@EnableTransactionManagement(mode = AdviceMode.ASPECTJ)
@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);
}
}
@Configuration
public class DatastoreConfig{
@Bean
public FactoryBean<SessionFactory> sessionFactory(EntityManagerFactory emf){
HibernateJpaSessionFactoryBean jpaSessionFactoryBean = new HibernateJpaSessionFactoryBean();
jpaSessionFactoryBean.setEntityManagerFactory(emf);
return jpaSessionFactoryBean;
}
}
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