JavaEE体系进行分层开发,事务处理位于业务层。
spring提供了分层设计业务层的事务处理方案,spring的事务控制是基于aop的。
一、PlatformTransactionManager
此接口是spring的事务管理器,提供了常用的操作事务的方法
管理事务的子类对象:
(1)DataSourceTransactionManager:使用SpringJDBC或IBatis进行持久化数据时使用
(2)HibernateTransactionManager:使用Hibernate版本进行持久化数据时使用
二、基于XML的声明式事务控制
配置步骤
第一步:配置事务管理器
第二步:配置事务的通知引用事务管理器
第三步:配置事务的属性
第四步:配置AOP切入点表达式
第五步:配置切入点表达式和事务通知的对应关系
<tx:method name=""/>name属性:用于匹配需要织入事务的方法,设置匹配规则isolation:事务的隔离级别,默认值是DEFAULT,数据库级别的propagation:表示是否开启事务,以什么样的策略开启:REQUIRED表示一定会开启事务,无论是增删改查都会开启SUPPORTS表示有事务就会开启事务,没有事务就不会开启,会在增删改的场景下开启事务,查询场景不会开启即对数据有影响就开启事务read-only:是否只读:true是 false否 ,默认值是true,在查询的业务场景下,会把该属性设置成truetimeout:表示超时时间,默认值是-1,永不超时,如果是正数的话,可以以秒为单位,设置超时时间rollback-for:是否开启回滚:true 除了传的这个异常回滚之外,所有异常都不回滚no-rollback-for 除了传的这个异常不回滚之外,所有异常回滚默认情况下所有的异常都回滚只有在增删该的业务场景下,才会去开启事务,查询业务场景下不用开启事务或者是只读就行
<?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:context="http://www.springframework.org/schema/context"xmlns:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd"><bean id="service" class="com.jy.tx.account.service.AccountServiceImpl"></bean><bean id="dao" class="com.jy.tx.account.dao.AccountDaoImpl"></bean><!--注册jdbcTemplate实例--><bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"><property name="dataSource" ref="dataSource"></property></bean><!--注册数据源实例--><bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"><!--注入源数据--><property name="url" value="jdbc:mysql://localhost:3306/test?serverTimezone=GMT&characterEncoding=utf-8"></property><property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property><property name="username" value="root"></property><property name="password" value="root"></property></bean><!--配置事务管理器--><bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><!--注入数据源实例--><property name="dataSource" ref="dataSource"></property></bean><!--配置事务通知,引用事务管理器--><tx:advice id="txAdvice" transaction-manager="dataSourceTransactionManager"><!--配置事务的属性--><tx:attributes><tx:method name="update*" propagation="REQUIRED" read-only="false"/><tx:method name="find*" propagation="SUPPORTS" read-only="true"/></tx:attributes></tx:advice><!--配置aop--><aop:config><!--配置一个切入点表达式--><aop:pointcut id="pt01" expression="execution(* com.jy.tx.account.service.*.*(..))"/><!--配置切入点和事务通知的对应关系--><aop:advisor advice-ref="txAdvice" pointcut-ref="pt01"></aop:advisor></aop:config></beans>
三、基于注解的声明式事务控制@Transactional 事务注解,可以修饰类,也可以修饰方法,修饰类时,该类下所有的方法都会加入事务的支持,修饰方法时只有指定方法会加入事务支持,方法的优先级比类高。
使用注解时事务管理器仍需要配置,但可以免去事务通知的配置。
在同一个类中,非事务方法调用事务方法,事务不会开启,或者说无事务注解的方法调用有事务注解的方法时,注解不会生效。
**@Transactional**的原理是什么?
首先@Transactional是基于spring aop的,对于spring中aop实现原理有了解的话,应该知道想要对一个方法进行代理的话,肯定需要定义切点。在@Transactional的实现中,同样如此,spring为我们定义了以 @Transactional 注解为植入点的切点,这样才能知道@Transactional注解标注的方法需要被代理。
有了切面定义之后,在spring的bean的初始化过程中,就需要对实例化的bean进行代理,并且生成代理对象。
生成代理对象的代理逻辑中,进行方法调用时,需要先获取切面逻辑,@Transactional注解的切面逻辑类似于@Around,在spring中是实现一种类似代理逻辑。
