Spring 声明式事务管理
在 Spring 中提供了两种事务管理的方式,分别是编程式事务管理和声明式事务管理。
在实际应用中,目前很少需要用到编程式事务管理,尽管它比较灵活,但写编程的过程会很繁琐。
Spring 的声明式事务是通过 Spring AOP 实现的,通过事务的声明性信息,Spring 负责将事务管理增加逻辑动态织入业务方法的相应连接点中。
这些逻辑包括获取线程绑定资源、开始事务、提交/回滚事务、进行异常转换和处理等工作。
使用声明式事务有两种配置方式:XML 配置和注解配置。
在实际项目中一般采用的是注解配置方式,所以这里只介绍注解配置声明式事务。
使用 @Transactional 注解
@Service
@Transactional //对业务类使用事务增强的标注
public class BbtFormImpl implements IBbtForm {
public Forum getForum(int foeumId) {
return forumDao.getForum(forumId)
}
...
}
因为注解本身具有一组普适性的默认事务属性,所以一般只要在业务类中添加一个 @Transactional 注解,就能完成业务类事务属性的配置。
当然,注解只提供元数据,本身并不能完成事务切面织入的功能。因此还需要在 Spring 配置中一行注解扫描驱动的配置
<?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:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
...
<!-- 注册事务管理注解扫描驱动 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
...
</beans>
如果是 springboot 项目,需要在启动类上加 @EnableTransactionManagement
@SpringBootApplication
@MapperScan("com.itle.credit.mapper")
@EnableTransactionManagement //开启事务支持
public class Main {
public static void main(String[] args) {
SpringApplication.run(Main.class, args);
}
}
@Transactional 的属性
注解本身具有一组普适性的默认属性,所以一般不需要手动设置事务注解的属性。当然也有一些特殊情况需要通过手工设置属性值去覆盖默认值。
在何处标注 @Transactional 注解
@Transactional 注解可以被应用在接口、接口方法、类、类的 public 方法上。
Spring 建议在业务实现类上使用 @Transactional 注解。因为这个注解设定为不能被继承,如果在业务接口上标注 @Transactional ,则不会被业务实现类继承,业务类就不会启动事务机制。
方法处的注解会覆盖类定义处的注解。
如果有些方法需要使用特殊的事务属性,则可以在类注解的基础上提供方法注解:
//1.类级注解,适用于类中所有public方法
@Transactional
public class BbtForum {
//2.采用额外的注解配置,它将覆盖类级注解
@Transactional(readOnly=true)
public Forum getForum(int foeumId) {
return forumDao.getForum(forumId)
}
...
}
@Transactional 注解失效
注意:@Transaction不起作用的:
- 静态(static )方法、final方法、私有化(private)方法
- 自调用内部方法(因为事务是依赖aop的,而aop是通过动态代理实现的)
小结
Spring 声明式事务是 Spring 中的亮点,也是被使用最多的功能之一。
Spring 事务管理是 Spring AOP 技术的精彩应用的案例。事务管理作为一个切面织入目标业务方法的周围,业务方法完全从事务代码中解脱出来,代码复杂度大大降低。
而 Spring 事务管理作为Spring 中的亮点,它也是难点之一。这里只是简单介绍了声明式事务的使用,而想要彻底掌握,还需要去了解他们内部的机制。