Spring中提供了七种事务的传播行为:

PROPAGATION_REQUIRED:默认值,最常用,统一事务,出现异常,全部回滚

其余参考Spring事务处理word文档。

0、原转账业务(不含事务处理)

MyAspect:

@Component
public class MyAspect {
@Autowired
UserMapper userMapper;
@Autowired
AccountMapper accountMapper; /**
* 判断是否能转账
* @param point 切入点
* @return 1 可以转账
*/
public int transAccount(ProceedingJoinPoint point){
//拿到切入点参数
Object[] args = point.getArgs();
//转出人id
int outId = (int)args[0];
//转账金额
double money = (double)args[2];
//转出人cid
int cidOut = userMapper.getCidById(outId);
//获取转出人账户余额
double balance = accountMapper.getMoney(cidOut);
//判断转出的账户余额与转出金额比较
//转出>余额 异常:余额不足
if (money>balance){
throw new RuntimeException("余额不足,转账失败");
}else {
//执行转账
try {
int i = (int)point.proceed();
return i;
} catch (Throwable throwable) {
throwable.printStackTrace();
}
}
return 0;
}
}

通过aop编程,给原转账业务增加上面的增强类方法(基于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" xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<aop:config>
<aop:pointcut id="p1" expression="execution(* com.yd.service.impl.AccountServiceImpl.transferAccountIn(..))"/> <aop:aspect ref="myAspect">
<aop:around method="transAccount" pointcut-ref="p1"></aop:around>
</aop:aspect>
</aop:config> <!-- 强制使用cglib代理-->
<aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy> </beans>

一、基于xml的事务

通过AOP编程,给转账业务添加事务处理功能

  • 在转账是可能出现时间延时或其他异常,导致事务不统一
  • 以下用aop方式,给转账业务添加事务
    • 在不用更改源代码的情况下添加事务处理

transaction.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 definitions here --> <!-- 配置事物管理器的切面 -->
<bean id="transactionMananger" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 配置事物传播行为 :其实就是哪些方法应该受什么样的事物控制-->
<tx:advice id="advice" transaction-manager="transactionMananger">
<tx:attributes>
<tx:method name="transferAccountIn" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice> <!-- 哪些类下的方法需要参与到当前的事物管理中,配置切入点 -->
<aop:config>
<aop:advisor advice-ref="advice" pointcut="execution(* com.yd.service.impl.AccountServiceImpl.*(..))"/>
</aop:config>
</beans>

切入点-AccountServiceImpl:

@Service
public class AccountServiceImpl implements AccountService {
@Autowired
AccountMapper accountMapper; @Autowired
UserMapper userMapper; @Override
public int transferAccountIn(int idOut, int idIn, double money) {
//转入人cid
int cidIn = userMapper.getCidById(idIn);
//转入金额
int in = accountMapper.updateIn(cidIn,money);
//模拟异常
System.out.println(1/0);
//转出人cid
int cidOut = userMapper.getCidById(idOut);
//转出金额
int out = accountMapper.updateOut(cidOut,money); return in + out;
}
}
  • 将事务添加在transferAccountIn()方法上,只要有异常,其中的事务全部回滚

运行代码:

public class Demo {
public static void main(String[] args) {
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("mybatis.xml", "spring.xml","aspect.xml","tansaction.xml");
AccountServiceImpl accountServiceImpl = (AccountServiceImpl)ac.getBean("accountServiceImpl");
int res = accountServiceImpl.transferAccountIn(2,1,900);
if (res==2){
System.out.println("转账成功!");
}else {
System.out.println("转账失败!");
}
}
}

运行结果:

  • 出现异常,事务回滚

二、基于注解的事务

1. 在transacion.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 definitions here --> <!-- 配置事物管理器的切面(必须要) -->
<bean id="transactionMananger" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<aop:aspectj-autoproxy proxy-target-class="true"/> <!--强制使用Cglib代理-->
<!-- 开启注解事务-->
<tx:annotation-driven transaction-manager="transactionMananger"></tx:annotation-driven>
</beans>

2.在相应的方法上添加注解

@Transactional(propagation = Propagation.REQUIRED)

  • 在类上加此注解,表示当前类下所有方法都参与指定的事务管理
  • 在方法上加此注解,表示该方法执行指定的事务管理
@Service
public class AccountServiceImpl implements AccountService {
@Autowired
AccountMapper accountMapper; @Autowired
UserMapper userMapper; @Override
@Transactional(propagation = Propagation.REQUIRED)
public int transferAccountIn(int idOut, int idIn, double money) {
//转入人cid
int cidIn = userMapper.getCidById(idIn);
//转入金额
int in = accountMapper.updateIn(cidIn,money);
System.out.println(1/0);
//转出人cid
int cidOut = userMapper.getCidById(idOut);
//转出金额
int out = accountMapper.updateOut(cidOut,money); return in + out;
}
}

运行代码(与前面一致):

public class Demo {
public static void main(String[] args) {
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("mybatis.xml", "spring.xml","aspect.xml","tansaction.xml");
AccountServiceImpl accountServiceImpl = (AccountServiceImpl)ac.getBean("accountServiceImpl");
int res = accountServiceImpl.transferAccountIn(2,1,900);
if (res==2){
System.out.println("转账成功!");
}else {
System.out.println("转账失败!");
}
}
}

运行结果:

同样会出现异常,回滚

  • 注解开发更方便
  • 需要修改源码,在源码上加注解

07-Spring的事务处理的更多相关文章

  1. 【Spring】Spring系列5之Spring支持事务处理

    5.Spring支持事务处理 5.1.事务准备 以上代码结构与AOP的前置通知.返回通知.异常通知.后置通知一样. 5.2.声明式事务 5.2.1.基于注解 5.2.2.基于配置文件 5. 3.事务传 ...

  2. Spring Batch事务处理

    事务模型描述 1.step之间事务独立 2.step划分成多个chunk执行,chunk事务彼此独立,互不影响:chunk开始开启一个事务,正常结束提交.chunk表示给定数量的item的操作集合,主 ...

  3. Spring框架——事务处理(编程式和声明式)

     一. 事务概述 ●在JavaEE企业级开发的应用领域,为了保证数据的完整性和一致性,必须引入数据库事务的概念,所以事务管理是企业级应用程序开发中必不可少的技术. ●事务就是一组由于逻辑上紧密关联而合 ...

  4. 【Spring】Spring之事务处理

    编程式事务 /** * 1. 根据DataSource去创建事务管理器 * 构造方法 , 参数1. DataSource */ DataSourceTransactionManager txManag ...

  5. 07 Spring框架 依赖注入(四)基于注解的依赖注入

    前面几节我们都在使用xml进行依赖的注入,但是在实际的开发中我们往往偏爱于使用注解进行依赖注入,因为这样更符合我们人的思维,并且更加快捷,本节就来讲述Spring基于注解的依赖注入: 信息注入注解 @ ...

  6. spring的事务处理

    说到事务,无非就是事务的提交commit和回滚rollback. 事务是一个操作序列,这些操作要么全部都执行成功,事务去提交,要么就是有一个操作失败,事务去回滚. 要知道事务的4大特性ACID.即原子 ...

  7. 07.Spring Bean 加载 - BeanDefinitionReader

    基本概念 BeanDefinitionReader ,该接口的作用就是加载 Bean. 在 Spring 中,Bean 一般来说都在配置文件中定义.而在配置的路径由在 web.xml 中定义.所以加载 ...

  8. 踩坑系列《六》Spring增加事务处理遇到异常解决办法

    当在对数据进行增删改操作时,需要用到事务的处理,所以在业务层中加入@Transactional注解,但是在执行业务操作的前面遇到异常,因此对异常进行抛出,但是数据又诡异地成功保存到数据库了. 解决方法 ...

  9. hibernate整合进spring后的事务处理

    单独使用hibernate处理事务 本来只用hibernate开发,从而可以省了DAO层实现数据库访问和跨数据库,也可以对代码进行更好的封装,当我们web中单独使用hibernate时,我们需要单独的 ...

  10. java 之DelayQueue,TaskDelayed,handlerFactory,dataChange消息配置.收发等.java spring事务处理TransactionTemplate

    java 之DelayQueue,TaskDelayed,handlerFactory,dataChange消息配置.收发等.java spring事务处理TransactionTemplate等. ...

随机推荐

  1. JS日期格式化方法 封装

    //--------------------------------------------------- // 日期格式化 // 格式 YYYY/yyyy/YY/yy 表示年份 // MM/M 月份 ...

  2. C/C++ FILE 和 fstream 用法详解

    FILE 是C语言自带的文件操作结构体, fstream 是C++的文件操作类,两者使用都比较常见,且用法比较类似,再次记录. 功能 FILE fstream 打开文件 FILE* fopen(cha ...

  3. 如何在matlab中快速绘制一个函数的图像

    在malab绘制曲线图,并在x,y轴上加上说明 直接贴代码 clear,clck=1:1:10;y1=pi./atan(sqrt(k))-1;plot(k,y1)xlabel('Rz');ylabel ...

  4. python机器学习——线性回归方法

    背景与原理: 线性回归是机器学习建模中最为简单的模型,也是计算起来最为直观的模型 所谓线性回归,我们要建立的是这样的模型:对一组数据,每组数据形如$(x_{1},...,x_{n},y)$,我们希望构 ...

  5. 04 ajax执行php并传递参数

    做这个事情之前要导入jQuery js的方式 _this.value1 = "abc"; _this.value2 = 1; $.ajax({ url: 'xxxxxx.php', ...

  6. python 冰墩墩

    1. python, turtles 以下为代码: import turtle # 设置一个画布 turtle.setup(800,600) turtle.speed(10) # 画左手和手内 tur ...

  7. AX2012 查询用户在线操作记录

    1 static void ExportSysClientAccessLog(Args _args) 2 { 3 SysClientAccessLog sysClientAccessLog; 4 5 ...

  8. vue移动端在线签名

    <template> <section class="signature"> <div class="signatureBox"& ...

  9. mybatis批量更新的几种方式和性能对比

    https://blog.csdn.net/csdnbeyoung/article/details/106258611

  10. L0范式、L1范式、L2范式解释通俗版

    L0范数是指向量中非0的元素的个数.(L0范数很难优化求解) L1范数是指向量中各个元素绝对值之和 L2范数是指向量各元素的平方和然后求平方根 L1范数可以进行特征选择,即让特征的系数变为0. L2范 ...