博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SpringBoot 注解事务声明式事务
阅读量:6094 次
发布时间:2019-06-20

本文共 14323 字,大约阅读时间需要 47 分钟。

hot3.png

对新人来说可能上手比springmvc要快,但是对于各位从springmvc转战到springboot的话,有些地方还需要适应下,尤其是xml配置。我个人是比较喜欢注解➕xml是因为看着方便,查找方便,清晰明了。但是xml完全可以使用注解代替,今天就扒一扒springboot中事务使用注解的玩法。

 

  springboot的事务也主要分为两大类,一是xml声明式事务,二是注解事务,注解事务也可以实现类似声明式事务的方法,关于注解声明式事务,目前网上搜索不到合适的资料,所以在这里,我将自己查找和总结的几个方法写到这里,大家共同探讨

 

springboot 之 xml事务

      可以使用 @ImportResource("classpath:transaction.xml") 引入该xml的配置,xml的配置如下

[java]  

  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"  
  4.     xmlns:tx="http://www.springframework.org/schema/tx"  
  5.     xsi:schemaLocation="  
  6.         http://www.springframework.org/schema/beans  
  7.         http://www.springframework.org/schema/beans/spring-beans.xsd  
  8.         http://www.springframework.org/schema/tx  
  9.         http://www.springframework.org/schema/tx/spring-tx.xsd  
  10.         http://www.springframework.org/schema/aop  
  11.         http://www.springframework.org/schema/aop/spring-aop.xsd">  
  12.           
  13.     <bean id="txManager"  
  14.         class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
  15.         <property name="dataSource" ref="dataSource" ></property>  
  16.     </bean>  
  17.     <tx:advice id="cftxAdvice" transaction-manager="txManager">  
  18.         <tx:attributes>  
  19.             <tx:method name="query*" propagation="SUPPORTS" read-only="true" ></tx:method>  
  20.             <tx:method name="get*" propagation="SUPPORTS" read-only="true" ></tx:method>  
  21.             <tx:method name="select*" propagation="SUPPORTS" read-only="true" ></tx:method>  
  22.             <tx:method name="*" propagation="REQUIRED" rollback-for="Exception" ></tx:method>  
  23.         </tx:attributes>  
  24.     </tx:advice>  
  25.      <aop:config>  
  26.         <aop:pointcut id="allManagerMethod" expression="execution (* com.exmaple.fm..service.*.*(..))" />  
  27.         <aop:advisor advice-ref="txAdvice" pointcut-ref="allManagerMethod" order="0" />  
  28.     </aop:config>  
  29.   
  30. </beans>  

 

 

springboot 启动类如下:

[java]  

  1. package com.example.fm;  
  2.    
  3. import org.springframework.boot.SpringApplication;  
  4. import org.springframework.boot.autoconfigure.SpringBootApplication;  
  5. import org.springframework.context.annotation.ImportResource;  
  6.    
  7. @ImportResource("classpath:transaction.xml")  
  8. @SpringBootApplication  
  9. public class Application {  
  10.    
  11.     public static void main(String[] args) {  
  12.         SpringApplication.run(Application.class, args);  
  13.     }  
  14.    
  15. }  

启动后即可开启事务,不过项目里导入了xml配置,如果不想导入xml配置,可以使用注解的方式。

 

springboot 之 注解事务

   注解事务讲解之前,需要先了解下spring创建代理的几个类,在spring内部,是通过BeanPostProcessor来完成自动创建代理工作的。BeanPostProcessor接口的实现只是在ApplicationContext初始化的时候才会自动加载,而普通的BeanFactory只能通过编程的方式调用之。根据  匹配规则的不同大致分为三种类别:

 

    a、匹配Bean的名称自动创建匹配到的Bean的代理,实现类BeanNameAutoProxyCreator

[java]  

  1. <bean id="testInterceptor" class="com.example.service.config.testInerceptor”></bean>  
  2.   
  3. <bean id="profileAutoProxyCreator" class="org.springframework.aop.framework.  
  4. autoproxy.BeanNameAutoProxyProxyCreator">  
  5. <bean>  
  6. <property name="beanNames">  
  7. <list>  
  8. <value>*Service</value>  
  9. </list>  
  10. </property>  
  11. <property name="interceptorNames">  
  12. <value> testInterceptor </value>  
  13. </property>  
  14. </bean>  

 

b、根据Bean中的AspectJ注解自动创建代理,实现类AnnotationAwareAspectJAutoProxyCreator

[java]  

  1. <aop:aspectj-autoproxy proxy-target-class="true"/>  
  2.   
  3. <bean id="annotationAwareAspectJAutoProxyCreatorTest" class="com.example.service.AnnotationAwareAspectJAutoProxyCreatorTest"/>  
  4. <aop:config>  
  5.     <aop:aspect ref="annotationAwareAspectJAutoProxyCreatorTest">  
  6.         <aop:around method="process" pointcut="execution (* com.example.service.fm..*.*(..))"/>  
  7.     </aop:aspect>  
  8. </aop:config>  

 

c、根据Advisor的匹配机制自动创建代理,会对容器中所有的Advisor进行扫描,自动将这些切面应用到匹配的Bean中,实现类DefaultAdvisorAutoProxyCreator

 

  接下来开讲注解开启事务的方法:

 

       1、Transactional注解事务

 

   需要在进行事物管理的方法上添加注解,或者偷懒的话直接在类上面添加该注解,使得所有的方法都进行事物的管理,但是依然需要在需要事务管理的类上都添加,工作量比较大,这里只是简单说下,具体的可以google或者bing

 

       2、注解声明式事务

 

  Component或Configuration中bean的区别,有时间我会专门写一篇来讲解下

 

  a.方式1,这里使用Component或Configuration事务都可以生效

[java]  

  1. package com.exmple.service.fm9.config;  
  2.    
  3. import java.util.Collections;  
  4. import java.util.HashMap;  
  5. import java.util.Map;  
  6.    
  7. import org.aspectj.lang.annotation.Aspect;  
  8. import org.springframework.aop.Advisor;  
  9. import org.springframework.aop.aspectj.AspectJExpressionPointcut;  
  10. import org.springframework.aop.support.DefaultPointcutAdvisor;  
  11. import org.springframework.beans.factory.annotation.Autowired;  
  12. import org.springframework.context.annotation.Bean;  
  13. import org.springframework.context.annotation.Configuration;  
  14. import org.springframework.stereotype.Component;  
  15. import org.springframework.transaction.PlatformTransactionManager;  
  16. import org.springframework.transaction.TransactionDefinition;  
  17. import org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource;  
  18. import org.springframework.transaction.interceptor.RollbackRuleAttribute;  
  19. import org.springframework.transaction.interceptor.RuleBasedTransactionAttribute;  
  20. import org.springframework.transaction.interceptor.TransactionAttribute;  
  21. import org.springframework.transaction.interceptor.TransactionInterceptor;  
  22.    
  23. /** 
  24.  * Created by guozp on 2017/8/28. 
  25.  */  
  26.   
  27. //@Component 事务依然生效  
  28. @Configuration  
  29. public class TxAdviceInterceptor {  
  30.    
  31.     private static final int TX_METHOD_TIMEOUT = 5;  
  32.     private static final String AOP_POINTCUT_EXPRESSION = "execution (* com.alibaba.fm9..service.*.*(..))";  
  33.    
  34.     @Autowired  
  35.     private PlatformTransactionManager transactionManager;  
  36.    
  37.     @Bean  
  38.     public TransactionInterceptor txAdvice() {  
  39.         NameMatchTransactionAttributeSource source = new NameMatchTransactionAttributeSource();  
  40.          /*只读事务,不做更新操作*/  
  41.         RuleBasedTransactionAttribute readOnlyTx = new RuleBasedTransactionAttribute();  
  42.         readOnlyTx.setReadOnly(true);  
  43.         readOnlyTx.setPropagationBehavior(TransactionDefinition.PROPAGATION_NOT_SUPPORTED );  
  44.         /*当前存在事务就使用当前事务,当前不存在事务就创建一个新的事务*/  
  45.         RuleBasedTransactionAttribute requiredTx = new RuleBasedTransactionAttribute();  
  46.         requiredTx.setRollbackRules(  
  47.             Collections.singletonList(new RollbackRuleAttribute(Exception.class)));  
  48.         requiredTx.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);  
  49.         requiredTx.setTimeout(TX_METHOD_TIMEOUT);  
  50.         Map<String, TransactionAttribute> txMap = new HashMap<>();  
  51.         txMap.put("add*", requiredTx);  
  52.         txMap.put("save*", requiredTx);  
  53.         txMap.put("insert*", requiredTx);  
  54.         txMap.put("update*", requiredTx);  
  55.         txMap.put("delete*", requiredTx);  
  56.         txMap.put("get*", readOnlyTx);  
  57.         txMap.put("query*", readOnlyTx);  
  58.         source.setNameMap( txMap );  
  59.         TransactionInterceptor txAdvice = new TransactionInterceptor(transactionManager, source);  
  60.         return txAdvice;  
  61.     }  
  62.    
  63.     @Bean  
  64.     public Advisor txAdviceAdvisor() {  
  65.         AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();  
  66.         pointcut.setExpression(AOP_POINTCUT_EXPRESSION);  
  67.         return new DefaultPointcutAdvisor(pointcut, txAdvice());  
  68.         //return new DefaultPointcutAdvisor(pointcut, txAdvice);  
  69.     }  
  70. }  

 

 b.方式1,这里使用Component或Configuration事务都可以生效

[java]  

  1. package com.exmple.service.fm9.config;  
  2.    
  3. import java.util.Collections;  
  4. import java.util.HashMap;  
  5. import java.util.Map;  
  6.    
  7. import org.springframework.aop.aspectj.AspectJExpressionPointcutAdvisor;  
  8. import org.springframework.beans.factory.annotation.Autowired;  
  9. import org.springframework.context.annotation.Bean;  
  10. import org.springframework.context.annotation.Configuration;  
  11. import org.springframework.stereotype.Component;  
  12. import org.springframework.transaction.PlatformTransactionManager;  
  13. import org.springframework.transaction.TransactionDefinition;  
  14. import org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource;  
  15. import org.springframework.transaction.interceptor.RollbackRuleAttribute;  
  16. import org.springframework.transaction.interceptor.RuleBasedTransactionAttribute;  
  17. import org.springframework.transaction.interceptor.TransactionAttribute;  
  18. import org.springframework.transaction.interceptor.TransactionAttributeSource;  
  19. import org.springframework.transaction.interceptor.TransactionInterceptor;  
  20.    
  21. /** 
  22.  * Created by guozp on 2017/8/29. 
  23.  */  
  24. //@Component 事务依然生效  
  25. @Configuration  
  26. public class TxAnoConfig {  
  27.     /*事务拦截类型*/  
  28.     @Bean("txSource")  
  29.     public TransactionAttributeSource transactionAttributeSource(){  
  30.         NameMatchTransactionAttributeSource source = new NameMatchTransactionAttributeSource();  
  31.          /*只读事务,不做更新操作*/  
  32.         RuleBasedTransactionAttribute readOnlyTx = new RuleBasedTransactionAttribute();  
  33.         readOnlyTx.setReadOnly(true);  
  34.         readOnlyTx.setPropagationBehavior(TransactionDefinition.PROPAGATION_NOT_SUPPORTED );  
  35.         /*当前存在事务就使用当前事务,当前不存在事务就创建一个新的事务*/  
  36.         //RuleBasedTransactionAttribute requiredTx = new RuleBasedTransactionAttribute();  
  37.         //requiredTx.setRollbackRules(  
  38.         //    Collections.singletonList(new RollbackRuleAttribute(Exception.class)));  
  39.         //requiredTx.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);  
  40.         RuleBasedTransactionAttribute requiredTx = new RuleBasedTransactionAttribute(TransactionDefinition.PROPAGATION_REQUIRED,  
  41.             Collections.singletonList(new RollbackRuleAttribute(Exception.class)));  
  42.         requiredTx.setTimeout(5);  
  43.         Map<String, TransactionAttribute> txMap = new HashMap<>();  
  44.         txMap.put("add*", requiredTx);  
  45.         txMap.put("save*", requiredTx);  
  46.         txMap.put("insert*", requiredTx);  
  47.         txMap.put("update*", requiredTx);  
  48.         txMap.put("delete*", requiredTx);  
  49.         txMap.put("get*", readOnlyTx);  
  50.         txMap.put("query*", readOnlyTx);  
  51.         source.setNameMap( txMap );  
  52.    
  53.         return source;  
  54.     }  
  55.    
  56.     /**切面拦截规则 参数会自动从容器中注入*/  
  57.     @Bean  
  58.     public AspectJExpressionPointcutAdvisor pointcutAdvisor(TransactionInterceptor txInterceptor){  
  59.         AspectJExpressionPointcutAdvisor pointcutAdvisor = new AspectJExpressionPointcutAdvisor();  
  60.         pointcutAdvisor.setAdvice(txInterceptor);  
  61.         pointcutAdvisor.setExpression("execution (* com.alibaba.fm9..service.*.*(..))");  
  62.         return pointcutAdvisor;  
  63.     }  
  64.    
  65.     /*事务拦截器*/  
  66.     @Bean("txInterceptor")  
  67.     TransactionInterceptor getTransactionInterceptor(PlatformTransactionManager tx){  
  68.         return new TransactionInterceptor(tx , transactionAttributeSource()) ;  
  69.     }  
  70. }  

 

 c.方式1,这里使用Component或Configuration事务都可以生效

[java]  

  1. package com.exmple.service.fm9.config;  
  2.    
  3. import java.util.Properties;  
  4.    
  5.    
  6. import org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator;  
  7. import org.springframework.beans.factory.annotation.Autowired;  
  8. import org.springframework.context.annotation.Bean;  
  9. import org.springframework.context.annotation.Configuration;  
  10. import org.springframework.jdbc.datasource.DataSourceTransactionManager;  
  11. import org.springframework.stereotype.Component;  
  12. import org.springframework.transaction.interceptor.TransactionInterceptor;  
  13.    
  14. /** 
  15.  * Created by guozp on 2017/8/28. 
  16.  * 
  17.  */  
  18. //@Component  
  19. @Configuration  
  20. public class TxConfigBeanName {  
  21.    
  22.     @Autowired  
  23.     private DataSourceTransactionManager transactionManager;  
  24.    
  25.     // 创建事务通知  
  26.    
  27.     @Bean(name = "txAdvice")  
  28.     public TransactionInterceptor getAdvisor() throws Exception {  
  29.    
  30.         Properties properties = new Properties();  
  31.         properties.setProperty("get*", "PROPAGATION_REQUIRED,-Exception,readOnly");  
  32.         properties.setProperty("add*", "PROPAGATION_REQUIRED,-Exception,readOnly");  
  33.         properties.setProperty("save*", "PROPAGATION_REQUIRED,-Exception,readOnly");  
  34.         properties.setProperty("update*", "PROPAGATION_REQUIRED,-Exception,readOnly");  
  35.         properties.setProperty("delete*", "PROPAGATION_REQUIRED,-Exception,readOnly");  
  36.    
  37.         TransactionInterceptor tsi = new TransactionInterceptor(transactionManager,properties);  
  38.         return tsi;  
  39.    
  40.     }  
  41.    
  42.     @Bean  
  43.     public BeanNameAutoProxyCreator txProxy() {  
  44.         BeanNameAutoProxyCreator creator = new BeanNameAutoProxyCreator();  
  45.         creator.setInterceptorNames("txAdvice");  
  46.         creator.setBeanNames("*Service", "*ServiceImpl");  
  47.         creator.setProxyTargetClass(true);  
  48.         return creator;  
  49.     }  
  50. }  

 

d.方式1,这里使用Component或Configuration并不是所有事务都可以生效,例如Configuration的时候如果打开注释部分的而且不把代码都移动到 defaultPointcutAdvisor(),事物会失效,具体原因暂时不明,如果各位有明白的,可以指点我下。

[java]  

  1. ackage com.alibaba.fm9.config;  
  2.    
  3. import java.util.Properties;  
  4.    
  5. import javax.sql.DataSource;  
  6.    
  7. import org.springframework.aop.aspectj.AspectJExpressionPointcut;  
  8. import org.springframework.aop.support.DefaultPointcutAdvisor;  
  9. import org.springframework.beans.factory.annotation.Autowired;  
  10. import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;  
  11. import org.springframework.context.annotation.Bean;  
  12. import org.springframework.context.annotation.Configuration;  
  13. import org.springframework.jdbc.datasource.DataSourceTransactionManager;  
  14. import org.springframework.stereotype.Component;  
  15. import org.springframework.transaction.PlatformTransactionManager;  
  16. import org.springframework.transaction.interceptor.TransactionInterceptor;  
  17.    
  18. /** 
  19.  * Created by guozp on 2017/8/28. 
  20.  *                       ??????? 
  21.  */  
  22. @Configuration //事务失效,都移动到一个方法不失效  
  23. //@Component // 事务可行,不用都移动到一个方法  
  24. public class TxOtherConfigDefaultBean {  
  25.    
  26.     public static final String transactionExecution = "execution (* com.alibaba.fm9..service.*.*(..))";  
  27.    
  28.     @Autowired  
  29.     private PlatformTransactionManager transactionManager;  
  30.    
  31.     //@Bean  
  32.     //@ConditionalOnMissingBean  
  33.     //public PlatformTransactionManager transactionManager() {  
  34.     //    return new DataSourceTransactionManager(dataSource);  
  35.     //}  
  36.    
  37.    
  38.     @Bean  
  39.     public TransactionInterceptor transactionInterceptor() {  
  40.         Properties attributes = new Properties();  
  41.         attributes.setProperty("get*", "PROPAGATION_REQUIRED,-Exception");  
  42.         attributes.setProperty("add*", "PROPAGATION_REQUIRED,-Exception");  
  43.         attributes.setProperty("update*", "PROPAGATION_REQUIRED,-Exception");  
  44.         attributes.setProperty("delete*", "PROPAGATION_REQUIRED,-Exception");  
  45.         //TransactionInterceptor txAdvice = new TransactionInterceptor(transactionManager(), attributes);  
  46.         TransactionInterceptor txAdvice = new TransactionInterceptor(transactionManager, attributes);  
  47.         return txAdvice;  
  48.     }  
  49.    
  50.    
  51.     //@Bean  
  52.     //public AspectJExpressionPointcut aspectJExpressionPointcut(){  
  53.     //    AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();  
  54.     //    pointcut.setExpression(transactionExecution);  
  55.     //    return pointcut;  
  56.     //}  
  57.    
  58.     @Bean  
  59.     public DefaultPointcutAdvisor defaultPointcutAdvisor(){  
  60.         //AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();  
  61.         //pointcut.setExpression(transactionExecution);  
  62.         //DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor();  
  63.         //advisor.setPointcut(pointcut);  
  64.         //advisor.setAdvice(transactionInterceptor());  
  65.         AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();  
  66.         pointcut.setExpression(transactionExecution);  
  67.         DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor();  
  68.         advisor.setPointcut(pointcut);  
  69.         Properties attributes = new Properties();  
  70.         attributes.setProperty("get*", "PROPAGATION_REQUIRED,-Exception");  
  71.         attributes.setProperty("add*", "PROPAGATION_REQUIRED,-Exception");  
  72.         attributes.setProperty("update*", "PROPAGATION_REQUIRED,-Exception");  
  73.         attributes.setProperty("delete*", "PROPAGATION_REQUIRED,-Exception");  
  74.         TransactionInterceptor txAdvice = new TransactionInterceptor(transactionManager, attributes);  
  75.         advisor.setAdvice(txAdvice);  
  76.         return advisor;  
  77.     }  
  78. }  

 

 简单来说,springboot使用上述注解的几种方式开启事物,可以达到和xml中声明的同样效果,但是却告别了xml,使你的代码远离配置文件。

转载于:https://my.oschina.net/xiaominmin/blog/1612240

你可能感兴趣的文章
Vue之项目搭建
查看>>
app内部H5测试点总结
查看>>
Docker - 创建支持SSH服务的容器镜像
查看>>
[TC13761]Mutalisk
查看>>
三级菜单
查看>>
Data Wrangling文摘:Non-tidy-data
查看>>
加解密算法、消息摘要、消息认证技术、数字签名与公钥证书
查看>>
while()
查看>>
常用限制input的方法
查看>>
Ext Js简单事件处理和对象作用域
查看>>
IIS7下使用urlrewriter.dll配置
查看>>
12.通过微信小程序端访问企查查(采集工商信息)
查看>>
WinXp 开机登录密码
查看>>
POJ 1001 Exponentiation
查看>>
HDU 4377 Sub Sequence[串构造]
查看>>
云时代架构阅读笔记之四
查看>>
WEB请求处理一:浏览器请求发起处理
查看>>
Lua学习笔记(8): 元表
查看>>
PHP经典算法题
查看>>
LeetCode 404 Sum of Left Leaves
查看>>