如何正确配置并使用Spring的@Transactional注解,避免常见事务管理陷阱?
- 内容介绍
- 文章标签
- 相关推荐
本文共计377个文字,预计阅读时间需要2分钟。
java
1.配置事务管理
使用CGLib代理,开启事务管理 @EnableTransactionManagement(proxyTargetClass=true) public class MybatisConfig { } 1、配置事务//这里使用的是Mybatis,Mybatis+Spring的整合配置请看我其他的代码片段 //启用注解事务管理,使用CGLib代理 @EnableTransactionManagement(proxyTargetClass = true) public class MybatisConfig { @Bean public DruidDataSource druidDataSource(){ //配置DataSource,省略 } @Bean public DataSourceTransactionManager transactionManager(){ DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(druidDataSource()); //note:事务管理器DataSourceTransactionManager中添加的DataSource,要 //和sqlSessionFactoryBean.setDataSource(druidDataSource())中的 //DataSource是相同的DataSource,异常才会生效 return transactionManager; } @Bean public SqlSessionFactoryBean sqlSessionFactory() throws IOException{ SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean(); sqlSessionFactoryBean.setDataSource(druidDataSource()); // sqlSessionFactoryBean的其他设置,省略 return sqlSessionFactoryBean; } } 2、事务使用注意事项
@Transactional @RequestMapping("/testTransaction")//这是一个spring的controller public void controller() { try { /** * 这里模拟2个不同的service处理业务,2个不同的数据库表, * (当然我们可以有很多个service在这里)我们的设想是 * 只要有一个service出了异常则全部回滚 */ //service1处理业务 //service2处理业务 } catch (Exception ex) { /** * @Transactional的机制是:只要抛出异常,则回滚 * 异常一定要抛出,这样try里面的整个session才会回滚,不然spring不做正确的回滚, * 如上面service2出现异常,如果这里的异常并未抛出,而是做了不抛出处理,那么上方 * 的service1会commit,service2才会回滚。如果想做整个方法一起回滚的话,这样是 * 不会成功的,所以这里一定要throw出去 */ throw ex; } 3、throw的异常处理:我们可以在统一的异常处理接口中处理我们知道的异常(存入数据库,生成logger日志,返回友好的异常展示等)
@Component //SpringMVC统一的异常处理类HandlerExceptionResolver public class ExceptionHandler implements HandlerExceptionResolver { @Override public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { //handle exception:存入数据库,生成logger日志,返回友好的异常展示等 return null; } }
本文共计377个文字,预计阅读时间需要2分钟。
java
1.配置事务管理
使用CGLib代理,开启事务管理 @EnableTransactionManagement(proxyTargetClass=true) public class MybatisConfig { } 1、配置事务//这里使用的是Mybatis,Mybatis+Spring的整合配置请看我其他的代码片段 //启用注解事务管理,使用CGLib代理 @EnableTransactionManagement(proxyTargetClass = true) public class MybatisConfig { @Bean public DruidDataSource druidDataSource(){ //配置DataSource,省略 } @Bean public DataSourceTransactionManager transactionManager(){ DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(druidDataSource()); //note:事务管理器DataSourceTransactionManager中添加的DataSource,要 //和sqlSessionFactoryBean.setDataSource(druidDataSource())中的 //DataSource是相同的DataSource,异常才会生效 return transactionManager; } @Bean public SqlSessionFactoryBean sqlSessionFactory() throws IOException{ SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean(); sqlSessionFactoryBean.setDataSource(druidDataSource()); // sqlSessionFactoryBean的其他设置,省略 return sqlSessionFactoryBean; } } 2、事务使用注意事项
@Transactional @RequestMapping("/testTransaction")//这是一个spring的controller public void controller() { try { /** * 这里模拟2个不同的service处理业务,2个不同的数据库表, * (当然我们可以有很多个service在这里)我们的设想是 * 只要有一个service出了异常则全部回滚 */ //service1处理业务 //service2处理业务 } catch (Exception ex) { /** * @Transactional的机制是:只要抛出异常,则回滚 * 异常一定要抛出,这样try里面的整个session才会回滚,不然spring不做正确的回滚, * 如上面service2出现异常,如果这里的异常并未抛出,而是做了不抛出处理,那么上方 * 的service1会commit,service2才会回滚。如果想做整个方法一起回滚的话,这样是 * 不会成功的,所以这里一定要throw出去 */ throw ex; } 3、throw的异常处理:我们可以在统一的异常处理接口中处理我们知道的异常(存入数据库,生成logger日志,返回友好的异常展示等)
@Component //SpringMVC统一的异常处理类HandlerExceptionResolver public class ExceptionHandler implements HandlerExceptionResolver { @Override public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { //handle exception:存入数据库,生成logger日志,返回友好的异常展示等 return null; } }

