声明式事务控制区别于编程式事务控制,声明式事务控制是以配置的形式达到事务控制的目的,实现了事务控制与业务逻辑的解耦合。
spring事务控制是基于AOP封装的,所以配置上是简化了的AOP配置流程
小知识:transaction(事务)一般会简写为tx,因为transaction音标是/træn'zækʃən/,单词首字母是t,zækʃən发音类似x,所以简写为tx.(老外的习惯就酱紫)
一、基于xml的声明式事务控制
1、配置平台事务管理器
如果dao层使用的非jdbc技术,这里class要配置为对应技术的管理器,对于jdbctemplate,mybatis都是基于jdbc,都可以配置为如下管理器
<bean id="platformManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 给管理器配置连接池 -->
<property name="dataSource" ref="dataSourceId"></property>
</bean>
2、事务的配置,对要被事务管控的方法进行配置
在这里被增强的方法即为AOP中的切点,事务即为增强
<!-- 配置增强的属性,即配置事务的属性 -->
<tx:advice id="txAdviceId" transaction-manager="platformManager">
<tx:attributes>
<!-- 配置被增强的切点的事务属性 name:被增强的切点名-->
<tx:method name="transferAccount" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" timeout="-1"/>
<!-- *代表任意方法 具体事务属性不进行配置,即 使用事务的默认属性-->
<tx:method name="*"></tx:method>
</tx:attributes>
</tx:advice>
事务的属性介绍
isolation:用于指定事务的隔离级别。默认值是DEFAULT
propagation:用于指定事务的传播行为。默认值是REQUIRED
read-only:用于指定事务是否只读。
timeout:用于指定事务的超时时间,默认值是-1,表示永不超时。如果指定了数值,以秒为单位。
rollback-for:用于指定一个异常,当产生该异常时,事务回滚,产生其他异常时,事务不回滚。不设置值,表示任何异常都回滚。
no-rollback-for:与rollback-for相反,指定一个异常,当产生该异常时,事务不回滚,产生其他异常时事务回滚。不设置值,表示任何异常都回滚
3、配置织入
需要注意的是,配置普通AOP织入使用<aop:aspect>标签,配置事务织入使用的是<aop:advisor >标签
<!-- 配置事务的织入,将增强与切点结合 -->
<aop:config>
<aop:pointcut id="pointCutId" expression="execution(* com.syx.service.impl.*.*(..))"/>
<aop:advisor advice-ref="txAdviceId" pointcut-ref="pointCutId"></aop:advisor>
</aop:config>
二、基于注解的声明式事务控制
1、相比于xml配置的方式,注解方式配置事务首先要在xml中添加组件扫描和开启事务注解驱动
<!--开启组件扫描-->
<context:component-scan base-package="需要被扫描的包名"></context:component-scan>
<!-- 开启事务注解驱动 -->
<tx:annotation-driven transaction-manager="platformManager"></tx:annotation-driven>
<!-- 配置平台事务管理器驱动 -->
<bean id="platformManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 给管理器配置连接池 -->
<property name="dataSource" ref="dataSourceId"></property>
</bean>
2、注解方式使用@Transactional代替xml中<tx:advice>和<aop:config>两个标签的功能,对需要事务控制的类或方法进行配置
该注解使用在类上,表示该类下的方法全部配置为该事务属性
该注解使用在方法上时,表示配置方法的事务属性
如果类上和方法上同时出现Transactional注解,则以方法上的配置为准。
@Service("studentServiceId")
@Transactional(isolation = Isolation.SERIALIZABLE,propagation = Propagation.REQUIRED)
public class studentServiceImpl implements studentService {
@Autowired
private studentDao studentDao;
@Override
@Transactional(isolation = Isolation.SERIALIZABLE,propagation = Propagation.REQUIRED, timeout = -1, readOnly = false)
public void transferAccount(int getId, int outId, int money) {
studentDao.getMoney(money, getId);
studentDao.pay(money, outId);
}
}