1. 程式人生 > >spring boot -- 事務

spring boot -- 事務

指針 except oot AC cond tex ack manager data-

  

事務

基礎

   分為 編程式事務 與 聲明式事務

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
}

  

spring boot -- 事務