1. 程式人生 > >SpringBoot 註解事務宣告式事務

SpringBoot 註解事務宣告式事務

springboot對新人來說可能上手比springmvc要快,但是對於各位從springmvc轉戰到springboot的話,有些地方還需要適應下,尤其是xml配置。我個人是比較喜歡註解➕xml是因為看著方便,查詢方便,清晰明瞭。但是xml完全可以使用註解代替,今天就扒一扒springboot中事務使用註解的玩法。

  springboot的事務也主要分為兩大類,一是xml宣告式事務,二是註解事務,註解事務也可以實現類似宣告式事務的方法,關於註解宣告式事務,目前網上搜索不到合適的資料,所以在這裡,我將自己查詢和總結的幾個方法寫到這裡,大家共同探討

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 啟動類如下:

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事務都可以生效

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事務都可以生效

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事務都可以生效

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(),事物會失效,具體原因暫時不明,如果各位有明白的,可以指點我下。

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,使你的程式碼遠離配置檔案。

相關推薦

SpringBoot 註解事務宣告事務

springboot對新人來說可能上手比springmvc要快,但是對於各位從springmvc轉戰到springboot的話,有些地方還需要適應下,尤其是xml配置。我個人是比較喜歡註解➕xml是因為看著方便,查詢方便,清晰明瞭。但是xml完全可以使用註解代替,今天就扒

spring boot基於註解宣告事務配置

spring boot基於註解的宣告式事務配置 事務配置 1、配置方式一 1)開啟spring事務管理,在spring boot啟動類添加註解@EnableTransactionManagement(proxyTargetClass = true);等同於xml配置方式的 &l

使用註解配置宣告事務

1.配置事物管理器 <bean id="transactionManager"  class="org.springframework.jdbc.datasource.DatasourceTransactionManager"> <property  n

註解驅動開發四純註解實現宣告事務(無xml)

配置類如下: @EnableTransactionManagement @ComponentScan("com.web.tx") @Configuration public class TxConfig

深入解讀Spring Framework事務管理(第四彈:基於@Transactional註解宣告事務管理)

基於註解的宣告式事務,主要使用的是@Transactional註解,下面我們來具體看一下。 使用@Transactional註解實現事務的例子 // 這個service我們要將他事務化 @Transactional public class Defa

事務管理及spring基於註解宣告事務管理的配置和用法

因為前幾天看一個專案文件出現“本系統採用基於Spring的宣告式事務控制”,才根據文件和程式碼瞭解了一下事務管理的相關知識。這裡對自己的學習做個總結。 一:相關概念 1.事務:事務是一系列的動作,它們

Spring 程式設計事務 宣告事務

程式設計式事務通用類: import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.datasource.DataSourceTransactionManager

Spring事務--宣告事務和程式設計事務

宣告式事務和程式設計式事務 宣告式事務是基於代理實現的。最小的力度是方法級。 程式設計式事務是基於事務模版來做的,具有較高的侵略性

宣告事務管理三:基於註解的配置

這種基於註解配置的宣告式事務管理方法式很簡單,很方便              (1) 像之前一樣恢復到初始狀態 (2) 配置事務管理器(注入連線池)       (3) 開啟註解

第十二講:12,spring宣告事務管理-註解

1,複製專案spring404 ,改名spring404-3。修改BankServiceImpl類,添加註解,package com.cruise.service.impl;import org.springframework.transaction.annotation.Tra

springboot(三) springboot開啟宣告事務

版權宣告:本文為博主原創文章,歡迎轉載,轉載請註明作者、原文超連結 ,博主地址:http://blog.csdn.net/forezp。 https://blog.csdn.net/forezp/article/details/70833629 轉載請標明出處: http://blog.csdn.n

淺談spring事務管理的2種方式:程式設計事務管理和宣告事務管理;以及@Transactional(rollbackFor=Exception.class)註解用法

事務的概念,以及特性: 百度百科介紹: ->資料庫事務(Database Transaction) ,是指作為單個邏輯工作單元執行的一系列操作,要麼完全地執行,要麼完全地不執行。 事務處理可以確保除非事務性單元內的所有操作都成功完成,否則不會永久更新面向資料的資源。通過

使用註解實現Spring的宣告事務管理

使用註解實現Spring的宣告式事務管理,更加簡單! 步驟:          1) 必須引入Aop相關的jar檔案          2) b

spring事物配置,宣告事務管理和基於@Transactional註解的使用

spring支援程式設計式事務管理和宣告式事務管理兩種方式。         程式設計式事務管理使用TransactionTemplate或者直接使用底層的PlatformTransactionManager。對於程式設計式事務管理,spring推薦使用Transactio

Spring第三天:Spring的AOP的註解開發、Spring的宣告事務、JdbcTemplate

目錄 1.Spring的AOP基於AspectJ的註解開發 1.1Spring基於ApsectJ的註解的AOP開發 1.1.1建立專案,引入jar包 1.1.2引入配置檔案 1.1.3編寫目標類並配置 1.1.4編寫切面類並配置 1.1.5使用註解的AOP物件目標類進

springboot開啟宣告事務

springboot開啟宣告式事務 轉載http://blog.csdn.net/forezp/article/details/70833629   springboot開啟事務很簡單,只需要一個註解@Transactional 就可以了。因為在springboot中已經預設對jp

關於宣告事務管理和註解事務

在javaweb操作中,當涉及到資料庫的持久化操作的時候就有一個大人物需要提起:事務 1,在原始的開發中事務可以通過在spring中配置進行操作,基本的原理就是,在spring中加入相應的sessionfactory(不同 的持久化框架不一樣,mybatis為sqlsess

spring事務管理之四:宣告事務管理:使用事務註解的方式

事務註解的方式,相對xml的方式來說,有優點,無需配置需要事務的業務方法的切點和事務屬性。但是也有缺點,就是需要在每個需要事務的業務方法上加上一個註解@Transaction,否則事務不會生效。 這裡沿用之前spring事務管理的程式碼: pom.xml依賴部分: <depen

spring宣告事務管理:基於註解的方式

1)在spring.xml中配置事務管理器DataSourceTransactionManager,<bean id="txManager" class="org.springframework.

SpringBoot宣告事務的簡單運用

關於事物的基本概念等這裡就不介紹了。 Spring宣告式事物的實現,有兩種方式;第一種是配置xml,第二種是使用相關注解(這兩種方式可詳見《程式設計師成長筆記(一)》的相關章節)。 SpringBoot中預設配置了第二種方式,所以,SpringBoot直接使用註解即可。下