spring boot -- 事务
Posted _陈昱先
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring boot -- 事务相关的知识,希望对你有一定的参考价值。
事务
基础
分为 编程式事务 与 声明式事务
import org.springframework.transaction.annotation
@Transactional() @Transactional
在service层使用@Transcational
@Transactional使用在类上表示类中的方法都是事务
一般在使用单元测试时,都会添加@Rollback来进行数据的回滚
@EnableTransactionManagement (@SpringBootApplication)
JPA默认开启transactional,且查询都为readOnly=true,可以看源码SimpleJpaRepository
spring boot专门配置事务的类为: org.springframework.boot.autoconfigure.transaction.TransactionalAutoConfiguration,
但是因为在TransactionManagerAutoConfiguration中开启了对声明式事务的支持
@ConditionalOnMissingBean
@Configuration
@EnableTransactionManagement
所以在Spring Boot中,不需要显示声明
在Spring Boot中,当我们使用了spring-boot-starter-jdbc或spring-boot-starter-data-jpa依赖的时候,框 架会自动默认分别注入DataSourceTransactionManager或JpaTransactionManager。所以我们不需要任何额外 配置就可以用@Transactional注解进行事务的使用。
问题
- 事务不回滚
a) 启动代理模式
b) shiro导致SpringBoot事务不起效
原因:shiro在启动配置时Spring还没有启动
解决方法:把原来在ShiroConfig里面初始化的getUserRealm与securityManager方法移动到一个新建的Spring监听器中进行初始化
c) 默认情况下,只对unchecked异常进行事务回滚,如果是checked异常,则不回滚
unchecked:派生于Error,RuntimeException(如空指针,1/0) 空指针,文件读写
checked: 其他的继承自java.lang.Exception的异常,如IOException,TimeOutException
解决方法: 对于checked异常不回滚的 增加注解
@Transaction(rollbackFor=Exception.class)
如果异常被try{} catch{}到,事务不会回滚
使用回滚需要抛出异常 try{} catch{throw new RuntimeException}
d) 数据库需要支持回滚
Innodb 与 myisam的区别
e) 是否开启对注解的解析
@EnableTransactionManagement
f) spring是否扫描到该包
g) 是否是方法的调用
使用代理模式,controller调用service的代理,进行操作
@Component public class TransactionConfig { @Autowired PlatformTransactionManager transactionManager; //获取配置器 public DeafultPointerAdvisor getAdvisor(){ //声明切点 AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut(); cut.setExpression("excution()"); //切点表达式 DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor(); advisor.setPointcut(pointcut); //放入切点 Properties attributes = new Properties(); //properties是一种容器 //get* 以get开头的函数 //PROPAGATIO_REQUIRED 如果是事务,则进行;不是事务,作为事务 //-Exception 异常回滚 attribute.setProperty("get*","PROPAGATIO_REQUIRED,readOnly,-Exception"); //transactionManager spring自动生成 TransactionInterceptor txAdvice = new TransactionInterceptor(transactionManager,attributes); advisor.setAdvice(txAdvice); return advisor; } }
@Autowired TransactionConfig transactionConfig; //定义代理类 public <T> T getObj(Object object){ ProxyFactoryBean factory = new ProxyFactoryBean(); factory.setTarget(object); factory.addAdvisor(transactionConfig.getAdvisor()); T tObject = (T)factory.getObject(); return tObject }
以上是关于spring boot -- 事务的主要内容,如果未能解决你的问题,请参考以下文章
Spring Boot 中使用 @Transactional 注解配置事务管理
Spring Boot 中使用 @Transactional 注解配置事务管理