• 第5章Spring 事务(测试)-Spring的事务注解(小项目中),AspectJ的AOP配置管理事务(大项目中)...


    第5章Spring 事务(测试)-Spring的事务注解(小项目中),AspectJ的AOP配置管理事务(大项目中)

    spring框架中提供的事务处理方案

    适合中小项目使用的, 注解方案。

    1. 1.适合中小项目使用的, 注解方案。
    2. spring框架自己用aop实现给业务方法增加事务的功能, 使用@Transactional注解增加事务。
    3. @Transactional注解是spring框架自己注解,放在public方法的上面,表示当前方法具有事务。
    4. 可以给注解的属性赋值,表示具体的隔离级别,传播行为,异常信息等等
    5. 使用@Transactional的步骤:
    6. 1.需要声明事务管理器对象
    7. "xx" class="DataSourceTransactionManager">

    1. 使用 Spring 的事务注解管理事务(掌握)

    通过@Transactional 注解方式,可将事务织入到相应 public 方法中,实现事务管理。

    1. @Transactional 的所有可选属性如下所示:
    2. ➢ propagation:用于设置事务传播属性。该属性类型为 Propagation 枚举,默认值为Propagation.REQUIRED。
    3. ➢ isolation:用于设置事务的隔离级别。该属性类型为 Isolation 枚举,默认值为Isolation.DEFAULT。
    4. ➢ readOnly:用于设置该方法对数据库的操作是否是只读的。该属性为 boolean,默认值为 false
    5. ➢ timeout:用于设置本操作与数据库连接的超时时限。单位为秒,类型为 int,默认值为-1,即没有时限。
    6. ➢ rollbackFor:指定需要回滚的异常类。类型为 Class[],默认值为空数组。当然,若只有一个异常类时,可以不使用数组。
    7. ➢ rollbackForClassName:指定需要回滚的异常类类名。类型为 String[],默认值为空数组。当然,若只有一个异常类时,可以不使用数组。
    8. ➢ noRollbackFor:指定不需要回滚的异常类。类型为 Class[],默认值为空数组。当然,若只有一个异常类时,可以不使用数组。
    9. ➢ noRollbackForClassName:指定不需要回滚的异常类类名。类型为 String[],默认值为空数组。
    10. 当然,若只有一个异常类时,可以不使用数组。
    11. 需要注意的是,@Transactional 若用在方法上,只能用于 public 方法上。对于其他非 public
    12. 方法,如果加上了注解@Transactional,虽然 Spring 不会报错,但不会将指定事务织入到该
    13. 方法中。因为 Spring 会忽略掉所有非 public 方法上的@Transaction 注解。
    14. @Transaction 注解在类上,则表示该类上所有的方法均将在执行时织入事务。
    • 实现注解的事务步骤:

      1. 声明事务管理器

        1. <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        2. <property name="dataSource" ref="myDataSource" />
        3. bean>
      2. 开启注解驱动

        1. <tx:annotation-driven transaction-manager="transactionManager" />
      3. 业务层 public 方法加入事务属性

      1. @Transactional(
      2. propagation = Propagation.REQUIRED,
      3. isolation = Isolation.DEFAULT,
      4. readOnly = false,
      5. rollbackFor = {
      6. NullPointerException.class, NotEnoughException.class
      7. }
    • 此时的spring配置文件

      1. "1.0" encoding="UTF-8"?>
      2. <beans xmlns="http://www.springframework.org/schema/beans"
      3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      4. xmlns:context="http://www.springframework.org/schema/context"
      5. xmlns:tx="http://www.springframework.org/schema/tx"
      6. xsi:schemaLocation="http://www.springframework.org/schema/beans
      7. http://www.springframework.org/schema/beans/spring-beans.xsd
      8. http://www.springframework.org/schema/context
      9. https://www.springframework.org/schema/context/spring-context.xsd
      10. http://www.springframework.org/schema/tx
      11. http://www.springframework.org/schema/tx/spring-tx.xsd">
      12. <context:property-placeholder location="classpath:jdbc.properties" />
      13. <bean id="myDataSource" class="com.alibaba.druid.pool.DruidDataSource"
      14. init-method="init" destroy-method="close">
      15. <property name="url" value="${jdbc.url}" />
      16. <property name="username" value="${jdbc.username}"/>
      17. <property name="password" value="${jdbc.passwd}" />
      18. <property name="maxActive" value="${jdbc.max}" />
      19. bean>
      20. <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
      21. <property name="dataSource" ref="myDataSource" />
      22. <property name="configLocation" value="classpath:mybatis.xml" />
      23. bean>
      24. <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
      25. <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
      26. <property name="basePackage" value="com.bjpowernode.dao"/>
      27. bean>
      28. <bean id="buyService" class="com.bjpowernode.service.impl.BuyGoodsServiceImpl">
      29. <property name="goodsDao" ref="goodsDao" />
      30. <property name="saleDao" ref="saleDao" />
      31. bean>
      32. <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
      33. <property name="dataSource" ref="myDataSource" />
      34. bean>
      35. <tx:annotation-driven transaction-manager="transactionManager" />
      36. beans>
    • com.bjpowernode.service.impl.BuyGoodsServiceImpl

      1. package com.bjpowernode.service.impl;
      2. import com.bjpowernode.dao.GoodsDao;
      3. import com.bjpowernode.dao.SaleDao;
      4. import com.bjpowernode.domain.Goods;
      5. import com.bjpowernode.domain.Sale;
      6. import com.bjpowernode.excep.NotEnoughException;
      7. import com.bjpowernode.service.BuyGoodsService;
      8. import org.springframework.transaction.annotation.Isolation;
      9. import org.springframework.transaction.annotation.Propagation;
      10. import org.springframework.transaction.annotation.Transactional;
      11. public class BuyGoodsServiceImpl implements BuyGoodsService {
      12. private SaleDao saleDao;
      13. private GoodsDao goodsDao;
      14. /**
      15. *
      16. * rollbackFor:表示发生指定的异常一定回滚.
      17. * 处理逻辑是:
      18. * 1) spring框架会首先检查方法抛出的异常是不是在rollbackFor的属性值中
      19. * 如果异常在rollbackFor列表中,不管是什么类型的异常,一定回滚。
      20. * 2) 如果你的抛出的异常不在rollbackFor列表中,spring会判断异常是不是RuntimeException,
      21. * 如果是一定回滚。
      22. *
      23. */
      24. /* @Transactional(
      25. propagation = Propagation.REQUIRED,
      26. isolation = Isolation.DEFAULT,
      27. readOnly = false,
      28. rollbackFor = {
      29. NullPointerException.class, NotEnoughException.class
      30. }
      31. )*/
      32. //使用的是事务控制的默认值, 默认的传播行为是REQUIRED,默认的隔离级别DEFAULT
      33. //默认抛出运行时异常,回滚事务。
      34. @Transactional(rollbackFor=Exception.class)
      35. @Override
      36. public void buy(Integer goodsId, Integer nums) {
      37. System.out.println("=====buy方法的开始====");
      38. //记录销售信息,向sale表添加记录
      39. Sale sale = new Sale();
      40. sale.setGid(goodsId);
      41. sale.setNums(nums);
      42. saleDao.insertSale(sale);
      43. //更新库存
      44. Goods goods = goodsDao.selectGoods(goodsId);
      45. if( goods == null){
      46. //商品不存在
      47. throw new NullPointerException("编号是:"+goodsId+",商品不存在");
      48. } else if( goods.getAmount() < nums){
      49. //商品库存不足
      50. throw new NotEnoughException("编号是:"+goodsId+",商品库存不足");
      51. }
      52. //修改库存了
      53. Goods buyGoods = new Goods();
      54. buyGoods.setId( goodsId);
      55. buyGoods.setAmount(nums);
      56. goodsDao.updateGoods(buyGoods);
      57. System.out.println("=====buy方法的完成====");
      58. }
      59. public void setSaleDao(SaleDao saleDao) {
      60. this.saleDao = saleDao;
      61. }
      62. public void setGoodsDao(GoodsDao goodsDao) {
      63. this.goodsDao = goodsDao;
      64. }
      65. }
    • 测试入下:

      1. 正常查询:

      2. 查询一个不存在的一条数据

      3. 购买的数量超过库中的数据

      4. 此时我们在查询一条正常的

    2.使用 AspectJ 的 AOP 配置管理事务(掌握)

    适合大型项目,有很多的类,方法,需要大量的配置事务,使用aspectj框架功能,在spring配置文件中声明类,方法需要的事务。这种方式业务方法和事务配置完全分离。

    1. Step1:maven 依赖 pom.xml

      1. 新加入 aspectj 的依赖坐标
      2. <dependency>
      3. <groupId>org.springframeworkgroupId>
      4. <artifactId>spring-aspectsartifactId>
      5. <version>5.2.5.RELEASEversion>
      6. dependency>
    2. Step:在容器中添加事务管理器

      1. <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
      2. <property name="dataSource" ref="myDataSource" />
      3. bean>
    3. 修改spring配置文件(重点)

      1. "1.0" encoding="UTF-8"?>
      2. <beans xmlns="http://www.springframework.org/schema/beans"
      3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      4. xmlns:context="http://www.springframework.org/schema/context"
      5. xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
      6. xsi:schemaLocation="http://www.springframework.org/schema/beans
      7. http://www.springframework.org/schema/beans/spring-beans.xsd
      8. http://www.springframework.org/schema/context
      9. https://www.springframework.org/schema/context/spring-context.xsd
      10. http://www.springframework.org/schema/tx
      11. http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
      12. <context:property-placeholder location="classpath:jdbc.properties" />
      13. <bean id="myDataSource" class="com.alibaba.druid.pool.DruidDataSource"
      14. init-method="init" destroy-method="close">
      15. <property name="url" value="${jdbc.url}" />
      16. <property name="username" value="${jdbc.username}"/>
      17. <property name="password" value="${jdbc.passwd}" />
      18. <property name="maxActive" value="${jdbc.max}" />
      19. bean>
      20. <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
      21. <property name="dataSource" ref="myDataSource" />
      22. <property name="configLocation" value="classpath:mybatis.xml" />
      23. bean>
      24. <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
      25. <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
      26. <property name="basePackage" value="com.bjpowernode.dao"/>
      27. bean>
      28. <bean id="buyService" class="com.bjpowernode.service.impl.BuyGoodsServiceImpl">
      29. <property name="goodsDao" ref="goodsDao" />
      30. <property name="saleDao" ref="saleDao" />
      31. bean>
      32. <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
      33. <property name="dataSource" ref="myDataSource" />
      34. bean>
      35. <tx:advice id="myAdvice" transaction-manager="transactionManager">
      36. <tx:attributes>
      37. <tx:method name="buy" propagation="REQUIRED" isolation="DEFAULT"
      38. rollback-for="java.lang.NullPointerException,com.bjpowernode.excep.NotEnoughException"/>
      39. <tx:method name="add*" propagation="REQUIRES_NEW" />
      40. <tx:method name="modify*" />
      41. <tx:method name="remove*" />
      42. <tx:method name="*" propagation="SUPPORTS" read-only="true" />
      43. tx:attributes>
      44. tx:advice>
      45. <aop:config>
      46. <aop:pointcut id="servicePt" expression="execution(* *..service..*.*(..))"/>
      47. <aop:advisor advice-ref="myAdvice" pointcut-ref="servicePt" />
      48. aop:config>
      49. beans>
    4. 此时达到的效果和上面spring的注解完成的效果是一样的,这里就不测试了。

  • 相关阅读:
    centos 7.9系统安装老版本jenkins,并解决插件问题
    SpringBoot自动配置原理解析
    微光互联 TX800-U 扫码器无法输出中文到光标的问题
    【Sentinel Go】新手指南、流量控制、熔断降级和并发隔离控制
    el-form for循环动态校验规则
    java计算机毕业设计二手车商城MyBatis+系统+LW文档+源码+调试部署
    Zookeeper集群安装教程
    ROS机器人实战,对标古月老师HRMRP机器人(一)——机器人总体方案设计
    Spring Boot中使用Swagger3.0.0版本构建RESTful APIs
    JVM的主要组成及其作用
  • 原文地址:https://blog.csdn.net/weixin_48370579/article/details/127827749