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

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

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

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

springboot 之 xml事务

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

springboot 启动类如下:

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")@SpringBootApplicationpublic 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

*Service
testInterceptor

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

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

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

       1、Transactional注解事务

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

       2、注解声明式事务

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

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

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 事务依然生效@Configurationpublic 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
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事务都可以生效

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 事务依然生效@Configurationpublic 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
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事务都可以生效

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@Configurationpublic 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(),事物会失效,具体原因暂时不明,如果各位有明白的,可以指点我下。

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 

你可能感兴趣的文章
CentOS7中搭建cobbler自动装机服务
查看>>
多线程设计模式:第二篇 - 四种基础模式
查看>>
域名跳转
查看>>
企业网站建设注意事项
查看>>
WPS Office 2019 发布Linux 个人版
查看>>
未来PCB行业互联网+发展趋势
查看>>
PDF如何旋转页面
查看>>
UI设计入门:解析设计标注规范和图标规范
查看>>
php模拟input 的file上传文件
查看>>
配置接口IP地址并通过默认路由配置实现全网互通。
查看>>
怎么在CAD编辑工具中绘制多边形线
查看>>
oracle rownum使用与分页
查看>>
我的友情链接
查看>>
我的友情链接
查看>>
exchange2003升级exchange2010思路----(3)卸载
查看>>
phoenixframework自动化测试平台webUI代码示例
查看>>
OpenStack阵营将推VDI平台 挑战思杰、VMware
查看>>
Java判断浏览器类型
查看>>
mikrotik dhcp server
查看>>
将TensorFlow训练的模型移植到Android手机
查看>>