JavaEE体系进行分层开发,事务处理位于业务层。
    spring提供了分层设计业务层的事务处理方案,spring的事务控制是基于aop的。

    一、PlatformTransactionManager
    此接口是spring的事务管理器,提供了常用的操作事务的方法
    管理事务的子类对象:
    (1)DataSourceTransactionManager:使用SpringJDBC或IBatis进行持久化数据时使用
    (2)HibernateTransactionManager:使用Hibernate版本进行持久化数据时使用

    二、基于XML的声明式事务控制
    配置步骤
    第一步:配置事务管理器
    第二步:配置事务的通知引用事务管理器
    第三步:配置事务的属性
    第四步:配置AOP切入点表达式
    第五步:配置切入点表达式和事务通知的对应关系

    1. <tx:method name=""/>
    2. name属性:用于匹配需要织入事务的方法,设置匹配规则
    3. isolation:事务的隔离级别,默认值是DEFAULT,数据库级别的
    4. propagation:表示是否开启事务,以什么样的策略开启:REQUIRED表示一定会开启事务,无论是增删改查都会开启
    5. SUPPORTS表示有事务就会开启事务,没有事务就不会开启,会在增删改的场景下开启事务,查询场景不会开启
    6. 即对数据有影响就开启事务
    7. read-only:是否只读:true false ,默认值是true,在查询的业务场景下,会把该属性设置成true
    8. timeout:表示超时时间,默认值是-1,永不超时,如果是正数的话,可以以秒为单位,设置超时时间
    9. rollback-for:是否开启回滚:true 除了传的这个异常回滚之外,所有异常都不回滚
    10. no-rollback-for 除了传的这个异常不回滚之外,所有异常回滚
    11. 默认情况下所有的异常都回滚
    12. 只有在增删该的业务场景下,才会去开启事务,查询业务场景下不用开启事务或者是只读就行
    1. <?xml version="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:aop="http://www.springframework.org/schema/aop"
    5. xmlns:context="http://www.springframework.org/schema/context"
    6. xmlns:tx="http://www.springframework.org/schema/tx"
    7. xsi:schemaLocation="http://www.springframework.org/schema/beans
    8. http://www.springframework.org/schema/beans/spring-beans.xsd
    9. http://www.springframework.org/schema/tx
    10. http://www.springframework.org/schema/tx/spring-tx.xsd
    11. http://www.springframework.org/schema/context
    12. http://www.springframework.org/schema/context/spring-context.xsd
    13. http://www.springframework.org/schema/aop
    14. http://www.springframework.org/schema/aop/spring-aop.xsd">
    15. <bean id="service" class="com.jy.tx.account.service.AccountServiceImpl"></bean>
    16. <bean id="dao" class="com.jy.tx.account.dao.AccountDaoImpl"></bean>
    17. <!--注册jdbcTemplate实例-->
    18. <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    19. <property name="dataSource" ref="dataSource"></property>
    20. </bean>
    21. <!--注册数据源实例-->
    22. <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    23. <!--注入源数据-->
    24. <property name="url" value="jdbc:mysql://localhost:3306/test?serverTimezone=GMT&amp;characterEncoding=utf-8"></property>
    25. <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property>
    26. <property name="username" value="root"></property>
    27. <property name="password" value="root"></property>
    28. </bean>
    29. <!--配置事务管理器-->
    30. <bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    31. <!--注入数据源实例-->
    32. <property name="dataSource" ref="dataSource"></property>
    33. </bean>
    34. <!--配置事务通知,引用事务管理器-->
    35. <tx:advice id="txAdvice" transaction-manager="dataSourceTransactionManager">
    36. <!--配置事务的属性-->
    37. <tx:attributes>
    38. <tx:method name="update*" propagation="REQUIRED" read-only="false"/>
    39. <tx:method name="find*" propagation="SUPPORTS" read-only="true"/>
    40. </tx:attributes>
    41. </tx:advice>
    42. <!--配置aop-->
    43. <aop:config>
    44. <!--配置一个切入点表达式-->
    45. <aop:pointcut id="pt01" expression="execution(* com.jy.tx.account.service.*.*(..))"/>
    46. <!--配置切入点和事务通知的对应关系-->
    47. <aop:advisor advice-ref="txAdvice" pointcut-ref="pt01"></aop:advisor>
    48. </aop:config>
    49. </beans>

    三、基于注解的声明式事务控制
    @Transactional 事务注解,可以修饰类,也可以修饰方法,修饰类时,该类下所有的方法都会加入事务的支持,修饰方法时只有指定方法会加入事务支持,方法的优先级比类高。
    使用注解时事务管理器仍需要配置,但可以免去事务通知的配置。
    在同一个类中,非事务方法调用事务方法,事务不会开启,或者说无事务注解的方法调用有事务注解的方法时,注解不会生效。
    image.png
    **@Transactional**的原理是什么?
    首先@Transactional是基于spring aop的,对于spring中aop实现原理有了解的话,应该知道想要对一个方法进行代理的话,肯定需要定义切点。在@Transactional的实现中,同样如此,spring为我们定义了以 @Transactional 注解为植入点的切点,这样才能知道@Transactional注解标注的方法需要被代理。
    有了切面定义之后,在spring的bean的初始化过程中,就需要对实例化的bean进行代理,并且生成代理对象。
    生成代理对象的代理逻辑中,进行方法调用时,需要先获取切面逻辑,@Transactional注解的切面逻辑类似于@Around,在spring中是实现一种类似代理逻辑。