在Spring框架中,提供了两种主要的事务管理方式:
- 编程式事务管理:通过编程的方式管理事务,即在代码中显式调用事务管理API。它给予开发者完全的控制,但是与业务代码的耦合度较高。
- 声明式事务管理:通常优先选择,利用注解或XML配置来管理事务,简化了事务管理,同时将事务管理代码从业务代码中解耦。
声明式事务管理
Spring的声明式事务管理建立在AOP之上,主要通过TransactionInterceptor
和TransactionProxyFactoryBean
或XML配置文件实现。最常用的方式是通过@Transactional
注解来使用。
- @Transactional:可以应用于接口定义、接口方法、类定义、类的公有方法上。
以下是声明式事务管理的实现原理:
-
当Spring应用启动时,通过
<tx:annotation-driven/>
标签或@EnableTransactionManagement
注解,Spring会查找带有@Transactional
注解的类和方法,并为其创建代理。 -
当调用代理对象的方法时,如果这个方法被
@Transactional
注解标记,TransactionInterceptor
会拦截这个方法调用的处理,它会在方法执行之前开始一个新的事务,在方法执行之后根据执行情况提交或回滚事务。 -
TransactionInterceptor
关联了PlatformTransactionManager
,这是一个事务管理器的接口,Spring提供了不同的实现,比如DataSourceTransactionManager
、JpaTransactionManager
等,用于不同持久化技术的事务管理。 -
PlatformTransactionManager
会使用TransactionDefinition
定义的规则来创建和管理TransactionStatus
,后者跟踪当前事务的状态信息。
代码层面,Transactional
注解的使用如下:
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDAO userDAO;
@Transactional
public void createUser(User user) {
userDAO.save(user);
// 其他逻辑...
}
}
Spring配置开启注解驱动的事务管理:
@Configuration
@EnableTransactionManagement
public class AppConfig {
// 配置数据源、事务管理器等bean...
}
或者在XML中配置:
<beans>
<!-- 开启注解事务 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
<!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
</beans>
编程式事务管理
在编程式事务管理中,需要手动编写代码来控制事务的边界。Spring提供了TransactionTemplate
或PlatformTransactionManager
来进行操作。
以下是使用TransactionTemplate
管理事务的例子:
public class UserServiceImpl implements UserService {
private final TransactionTemplate transactionTemplate;
// 通过构造器注入
public UserServiceImpl(PlatformTransactionManager transactionManager) {
this.transactionTemplate = new TransactionTemplate(transactionManager);
}
public User createUser(final User user) {
return transactionTemplate.execute(new TransactionCallback<User>() {
public User doInTransaction(TransactionStatus status) {
try {
userDAO.save(user);
// 其他逻辑...
} catch (SomeBusinessException ex) {
status.setRollbackOnly();
throw ex;
}
return user;
}
});
}
}
编程式事务管理提供了更细粒度的事务控制,但通常情况下更推荐使用声明式事务管理,因为它能够更好地维护业务逻辑和事务控制的分离。
总结
Spring事务管理是Spring核心功能之一,提供了强大灵活的事务管理能力。声明式事务管理是首选方式,因为它易于使用且几乎与业务代码无耦合。编程式事务管理则提供了更多的控制,但也增加了复杂性。在实际的开发中,应根据具体需求选择合适的事务管理方式。