SpringBoot注解事务声明式事务
对新⼈来说可能上⼿⽐springmvc要快,但是对于各位从springmvc转战到springboot的话,有些地⽅还需要适应下,尤其是xml配置。我个⼈是⽐较喜欢注解 xml是因为看着⽅便,查⽅便,清晰明了。但是xml完全可以使⽤注解代替,今天就扒⼀扒springboot中事务使⽤注解的玩法。
springboot的事务也主要分为两⼤类,⼀是xml声明式事务,⼆是注解事务,注解事务也可以实现类似声明式事务的⽅法,关于注解声明式事务,⽬前⽹上搜索不到合适的资料,所以在这⾥,我将⾃⼰查和总结的⼏个⽅法写到这⾥,⼤家共同探讨
springboot 之 xml事务
可以使⽤ @ImportResource("l") 引⼊该xml的配置,xml的配置如下
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="/schema/beans"
xmlns:xsi="/2001/XMLSchema-instance" xmlns:aop="/schema/aop"
xmlns:tx="/schema/tx"
xsi:schemaLocation="
/schema/beans
/schema/beans/spring-beans.xsd
/schema/tx
/schema/tx/spring-tx.xsd
/schema/aop
/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 (* aple.fm..service.*.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="allManagerMethod" order="0" />
</aop:config>
</beans>
springboot 启动类如下:
ample.fm;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import t.annotation.ImportResource;
@ImportResource("l")
@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="stInerceptor”></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="ample.service.AnnotationAwareAspectJAutoProxyCreatorTest"/>
spring mvc和boot区别<aop:config>
<aop:aspect ref="annotationAwareAspectJAutoProxyCreatorTest">
<aop:around method="process" pointcut="execution (* ample.service.fm..*.*(..))"/>
</aop:aspect>
</aop:config>
c、根据Advisor的匹配机制⾃动创建代理,会对容器中所有的Advisor进⾏扫描,⾃动将这些切⾯应⽤到匹配的Bean中,实现类DefaultAdvisorAutoProxyCreator
接下来开讲注解开启事务的⽅法:
1、Transactional注解事务
需要在进⾏事物管理的⽅法上添加注解@Transactional,或者偷懒的话直接在类上⾯添加该注解,使得所有的⽅法都进⾏事物的管理,但是依然需要在需要事务管理的类上都添加,⼯作量⽐较⼤,这⾥只是简单说下,具体的可以google或者bing
2、注解声明式事务
Component或Configuration中bean的区别,有时间我会专门写⼀篇来讲解下
a.⽅式1,这⾥使⽤Component或Configuration事务都可以⽣效
ple.fig;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.aspectj.lang.annotation.Aspect;
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 t.annotation.Bean;
import t.annotation.Configuration;
import org.springframework.stereotype.Component;
import ansaction.PlatformTransactionManager;
import ansaction.TransactionDefinition;
import ansaction.interceptor.NameMatchTransactionAttributeSource;
import ansaction.interceptor.RollbackRuleAttribute;
import ansaction.interceptor.RuleBasedTransactionAttribute;
import ansaction.interceptor.TransactionAttribute;
import ansaction.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事务都可以⽣效
ple.fig;
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 t.annotation.Bean;
import t.annotation.Configuration;
import org.springframework.stereotype.Component;
import ansaction.PlatformTransactionManager;
import ansaction.TransactionDefinition;
import ansaction.interceptor.NameMatchTransactionAttributeSource;
import ansaction.interceptor.RollbackRuleAttribute;
import ansaction.interceptor.RuleBasedTransactionAttribute;
import ansaction.interceptor.TransactionAttribute;
import ansaction.interceptor.TransactionAttributeSource;
import ansaction.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事务都可以⽣效
ple.fig;
import java.util.Properties;
import org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator;
import org.springframework.beans.factory.annotation.Autowired;
import t.annotation.Bean;
import t.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Component;
import ansaction.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;
}
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论