zoukankan      html  css  js  c++  java
  • 07-Spring的事务处理

    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("转账失败!");
            }
        }
    }
    

    运行结果:

    同样会出现异常,回滚

    • 注解开发更方便
    • 需要修改源码,在源码上加注解
  • 相关阅读:
    ryzen nvidia hackintosh
    mysql count 主键之坑
    git命令
    MYSQL 注释
    yaf twig配置
    1.YAF 的安装
    yaf nginx 设置
    ubuntu 16 阿里云 vsftpd
    win10下 homestead 安装
    活动调度
  • 原文地址:https://www.cnblogs.com/soft-test/p/14970571.html
Copyright © 2011-2022 走看看