1. 程式人生 > 實用技巧 >Springboot使用PlatformTransactionManager介面的事務處理

Springboot使用PlatformTransactionManager介面的事務處理

1、SpringBoot中可以使用PlatformTransactionManager介面來實現事務的統一控制,而進行控制的時候也可以採用註解或者AOP切面配置形式來完成,建議進行Aop切面進行事務管理,但是要寫好註釋,不然一些人後期找程式碼邏輯很容易看懵逼的。

在業務層的方法上啟用事務控制,可以加到方法上,也可以加到該業務類上,根據自己的需求來進行。

 1 package com.demo.service.impl;
 2 
 3 import java.util.List;
 4 
 5 import org.springframework.beans.factory.annotation.Autowired;
6 import org.springframework.stereotype.Service; 7 import org.springframework.transaction.annotation.Propagation; 8 import org.springframework.transaction.annotation.Transactional; 9 10 import com.demo.dao.UserDao; 11 import com.demo.po.UserInfo; 12 import com.demo.service.UserService; 13 14 @Service
15 public class UserServiceImpl implements UserService { 16 17 @Autowired 18 private UserDao userDao; 19 20 /** 21 * 在業務層的方法上啟用事務管理 22 */ 23 @Transactional(propagation = Propagation.REQUIRED, readOnly = true) 24 @Override 25 public List<UserInfo> findAll() { 26
27 return userDao.findAll(); 28 } 29 30 }

在程式主類中還需要配置事務管理註解,使用註解@EnableTransactionManagement開啟事務。

 1 package com.demo;
 2 
 3 import org.springframework.boot.SpringApplication;
 4 import org.springframework.boot.autoconfigure.SpringBootApplication;
 5 import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
 6 import org.springframework.transaction.annotation.EnableTransactionManagement;
 7 
 8 @SpringBootApplication // 啟動Springboot程式,而後自帶子包掃描
 9 @EnableJpaRepositories(basePackages = "com.demo.dao")
10 @EnableTransactionManagement // 啟動事務管理
11 public class DemoApplication {
12 
13     public static void main(String[] args) {
14         // 啟動Springboot程式
15         SpringApplication.run(DemoApplication.class, args);
16     }
17 
18 }

如果在業務層中定義@Transactional註解實現事務的控制,全部使用註解控制必然會造成程式碼的大量重複。在實際工作中,SpringBoot與事務結合最好的控制方法就是定義一個事務的配置類。取消業務Service層的事務註解配置,並定義TransactionConfig配置類,如下所示:

 1 package com.demo.config;
 2 
 3 import java.util.HashMap;
 4 import java.util.Map;
 5 
 6 import org.aspectj.lang.annotation.Aspect;
 7 import org.springframework.aop.Advisor;
 8 import org.springframework.aop.aspectj.AspectJExpressionPointcut;
 9 import org.springframework.aop.support.DefaultPointcutAdvisor;
10 import org.springframework.beans.factory.annotation.Autowired;
11 import org.springframework.context.annotation.Bean;
12 import org.springframework.context.annotation.Configuration;
13 import org.springframework.transaction.PlatformTransactionManager;
14 import org.springframework.transaction.TransactionDefinition;
15 import org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource;
16 import org.springframework.transaction.interceptor.RuleBasedTransactionAttribute;
17 import org.springframework.transaction.interceptor.TransactionAttribute;
18 import org.springframework.transaction.interceptor.TransactionInterceptor;
19 
20 @Configuration // 定義配置Bean
21 @Aspect // 採用Aop切面處理,定義切面類,切面通常是指封裝的用於橫向插入系統功能(事務、日誌)的類。
22 public class TransactionConfig {
23 
24     private static final int TRANSACTION_METHOD_TIMEOUT = 5; // 事務超時時間為5秒鐘
25 
26     // 定義切面表示式
27     private static final String AOP_POINTCUT_EXPRESSION = "execution(* com.demo..service.*.*(..))";
28 
29     // 注入事務管理物件
30     @Autowired
31     private PlatformTransactionManager transactionManager;
32 
33     /**
34      * 切面名稱必須為txAdvice
35      * 
36      * @return
37      */
38     @Bean(value = "txAdvice")
39     public TransactionInterceptor transactionConfig() {
40         // 定義只讀事務控制,該事務不需要啟動事務支援
41         RuleBasedTransactionAttribute readOnly = new RuleBasedTransactionAttribute();
42         // 設定只讀事務
43         readOnly.setReadOnly(true);
44         readOnly.setPropagationBehavior(TransactionDefinition.PROPAGATION_NOT_SUPPORTED);
45 
46         // 定義更新事務,同時設定事務操作的超時時間
47         RuleBasedTransactionAttribute required = new RuleBasedTransactionAttribute();
48         required.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
49         // 設定事務超時時間為5秒鐘
50         required.setTimeout(TRANSACTION_METHOD_TIMEOUT);
51 
52         // 定義業務切面
53         Map<String, TransactionAttribute> transactionmap = new HashMap<String, TransactionAttribute>();
54         transactionmap.put("add*", required);
55         transactionmap.put("edit*", required);
56         transactionmap.put("delete*", required);
57         transactionmap.put("get*", readOnly);
58         transactionmap.put("list*", readOnly);
59         transactionmap.put("find*", readOnly);
60 
61         // 使用名稱匹配
62         NameMatchTransactionAttributeSource source = new NameMatchTransactionAttributeSource();
63         source.setNameMap(transactionmap);
64 
65         // 對設定名稱的方法進行事務操作
66         TransactionInterceptor transactionInterceptor = new TransactionInterceptor();
67         transactionInterceptor.setTransactionManager(transactionManager);
68         transactionInterceptor.setTransactionAttributeSource(source);
69 
70         // 返回事務資訊
71         return transactionInterceptor;
72     }
73 
74     @Bean
75     public Advisor transactionAdviceAdvisor() {
76         AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
77         // 定義切面
78         pointcut.setExpression(AOP_POINTCUT_EXPRESSION);
79         DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor(pointcut, transactionConfig());
80         return advisor;
81     }
82 
83 }

此時程式中的事務控制可以利用TransactionConfig類結合AspectJ切面與業務層中的方法匹配,而後就不再需要業務方法使用@Transactional註解重複定義了,需要注意的是啟動主類要加上@EnableTransactionManagement啟動事務管理。