文章来源: 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 启动类如下:

  

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

初始使用:

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;
}
}

  

后修改如下:

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

  

SpringBoot 注解事务声明式事务的更多相关文章

  1. spring基于注解的声明式事务控制

    package com.hope.service.impl;import com.hope.dao.IAccountDao;import com.hope.domain.Account;import ...

  2. 28Spring_的事务管理_银行转账业务加上事务控制_基于注解进行声明式事务管理

    将applicationContext.xml 和 AccountServiceImpl 给备份一个取名为applicationContext2.xml 和 AccountServiceImpl2.j ...

  3. spring注解开发-声明式事务(源码)

    1. 环境搭建与测试 1)导入相关依赖 数据源.数据库驱动.Spring-jdbc模块 <dependency> <groupId>org.springframework< ...

  4. 阶段3 2.Spring_10.Spring中事务控制_8 spring基于纯注解的声明式事务控制

    新建项目 把之前项目src下的内容全部复制过来 pom.xml内复制过来 开始配置 新建一个config的包,然后再新建配置文件类SpringConfiguration @Configuration这 ...

  5. 阶段3 2.Spring_10.Spring中事务控制_7 spring基于注解的声明式事务控制

    创建新项目 复制上一个pom.xml的内容.依赖和打包的方式 再复制src的代码过来 bean.xml.多导入context的声明 Service的实现类增加注解 dao的set方法删掉 通过Auto ...

  6. spring下春注解的声明式事务控制

    package com.hope.test;import com.hope.domain.Account;import com.hope.service.IAccountService;import ...

  7. spring事物配置,声明式事务管理和基于@Transactional注解的使用

    http://blog.csdn.net/bao19901210/article/details/41724355 http://www.cnblogs.com/leiOOlei/p/3725911. ...

  8. 事务之三:编程式事务、声明式事务(XML配置事务、注解实现事务)

    Spring2.0框架的事务处理有两大类: JdbcTemplate操作采用的是JDBC默认的AutoCommit模式,也就是说我们还无法保证数据操作的原子性(要么全部生效,要么全部无效),如: Jd ...

  9. spring事务配置,声明式事务管理和基于@Transactional注解的使用(转载)

    原文地址:http://blog.csdn.net/bao19901210/article/details/41724355 事务管理对于企业应用来说是至关重要的,好使出现异常情况,它也可以保证数据的 ...

随机推荐

  1. Ubuntu source insight3稳定性

    Ubuntu 14.04 中安装了source insight3,用wine打开.导入工程,开始查看代码. 原来是直接导入了Android所有的源码,SI同步文件很慢.而且容易出现窗口变灰色的情况.经 ...

  2. jenkins - MultiJob使用

    我们如果使用jenkins需要由串行,并行,传递参数和等待执行的功能的话,那我们会用到jenkins里面的两个东西:MultiJob和pipeline 这里我介绍下MultiJob的使用 实例任务的拓 ...

  3. maven-配置文件配置src/resource下的文件

    classpath*:只找到applicationContext.xml classpath:/找到了所有

  4. (转)eclipse导入Gradle项目

    场景:最近在学习spring实战(第4版),下载完源码后发现不是maven工程,使用Gradle构建. 1准备工作 1.1 安装插件 打开eclipse,Help——Marketplace,搜索bui ...

  5. HDU1027 Ignatius and the Princess II

    Problem Description Now our hero finds the door to the BEelzebub feng5166. He opens the door and fin ...

  6. RequireJs加载Codemirror,配合AngularJS的坑

    requireJS加载codemirror,并且配合angularJs一起使用的时候,高亮显示代码编辑器.要注意以下几点: 1:普通Js加载CodeMirror  代码如下: <!DOCTYPE ...

  7. [补档][COGS 426]血帆海盗

    [COGS 426]血帆海盗 题目 传送门:http://cogs.pro/cogs/problem/problem.php?pid=426 随着资本的扩大,藏宝海湾贸易亲王在卡利姆多和东部王国大陆各 ...

  8. [硬件]_ELVE_VS2015下opencv3.3的配置问题

    0x00  引言 最近想搞一下摄像头,但是我的Windows版本是64位的,opencv3.3貌似也只支持64位系统了,所以就配置一下win10+vs2015+opencv3.3的环境变量,具体下载和 ...

  9. RSA加密解密及RSA加签验签

    RSA安全性应用场景说明 在刚接触RSA的时候,会混淆RSA加密解密和RSA加签验签的概念.简单来说加密解密是公钥加密私钥解密,持有公钥(多人持有)可以对数据加密,但是只有持有私钥(一人持有)才可以解 ...

  10. ios播放音乐

    1.背景音乐播放    循环播放长音乐  支持mp3格式 #import <AVFoundation/AVFoundation.h>: NSString *musicFilePath = ...