SpringBoot事务处理

xiaoxiao2021-02-28  42

SpringBoot 注解事务声明式事务

  文章来源: http://www.cnblogs.com/guozp/articles/7446477.html 

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

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

    文章来源: http://www.cnblogs.com/guozp/articles/7446477.html 

springboot 之 xml事务

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

  

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" ></property> </bean> <tx:advice id="cftxAdvice" transaction-manager="txManager"> <tx:attributes> <tx:method name="query*" propagation="SUPPORTS" read-only="true" ></tx:method> <tx:method name="get*" propagation="SUPPORTS" read-only="true" ></tx:method> <tx:method name="select*" propagation="SUPPORTS" read-only="true" ></tx:method> <tx:method name="*" propagation="REQUIRED" rollback-for="Exception" ></tx:method> </tx:attributes> </tx:advice> <aop:config> <aop:pointcut id="allManagerMethod" expression="execution (* com.exmaple.fm..service.*.*(..))" /> <aop:advisor advice-ref="txAdvice" pointcut-ref="allManagerMethod" order="0" /> </aop:config> </beans>

springboot 启动类如下:

  

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

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

springboot 之 注解事务

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

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

    

<bean id="testInterceptor" class="com.example.service.config.testInerceptor”></bean> <bean id="profileAutoProxyCreator" class="org.springframework.aop.framework. autoproxy.BeanNameAutoProxyProxyCreator"> <bean> <property name="beanNames"> <list> <value>*Service</value> </list> </property> <property name="interceptorNames"> <value> testInterceptor </value> </property> </bean>

 

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

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

 

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

  

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

       1、Transactional注解事务

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

       2、注解声明式事务

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

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

   

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

  

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

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

  

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

 

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

  

 

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

初始使用:

 

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

  

 

后修改如下:

 

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

    

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

    如果有错误的地方,望各位指正。如有其它问题,可以联系

   文章来源: http://www.cnblogs.com/guozp/articles/7446477.html 

转载请注明原文地址: https://www.6miu.com/read-2629413.html

最新回复(0)