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注解进行事务的使用。

问题

  1. 事务不回滚

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
}

  

猜你喜欢

转载自www.cnblogs.com/cyx-garen/p/9047170.html
今日推荐