通过以下方法配置的注解事务可以在Service类使用,但无法在SpringMVC的Controller类中使用。
上网查过很多资料,也翻阅过官方文档,官网是说Servlet中的WebApplicationContext与ContextLoaderListener加载的WebApplicationContext有所不同,如下图:
查阅资料后得知,传统标签或Java注解配置方式的 @EnableTransactionManager是通过SpringAOP的环绕切片实现,只能作用在与环绕切片在同一上下文中的Bean的方法上。
例如:在Root WebApplicationContext中声明,就只能作用在这个Context的services和repositories中,但没法作用在Controllers中,所以Controller中的@Transational注解会无效。
关于不使用SpringBoot时的解决方案是在web.xml配置中使用为DispatcherServlet初始化时传入带有标签的上下文。
现在我想问如何以Java代码配置方式+SpringBoot实现在Controllers中使用@Transactional注解?
以下是我的尝试,先给出Controller部分代码:
第一种SpringBoot配置方式:
这种方式实践结果是失败的,程序抛出 javax.persistence.TransactionRequiredException: Executing an update/delete query 异常。
回答
我是这么用的:
@Configuration
@ConfigurationProperties(locations = "classpath:server.yml",prefix = "mybatis")
public class DataSourceConf {
private String url;
private String username;
private String password;
@Bean
public DataSource dataSource(){
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
dataSource.setTestWhileIdle(true);
dataSource.setValidationQuery("select 1");
// dataSource.setDefaultAutoCommit(false); // 默认事务管理器提交的,没用
return dataSource;
}
/**
* spring transaction manager
*/
@Bean
public DataSourceTransactionManager transactionManager(DataSource rdsDataSource) {
return new DataSourceTransactionManager(rdsDataSource);
}
/**
* mybatis session factory 。。。
*/
}