DataSourceTransactionManager
和 @Transactional
是 Spring 框架中与事务管理相关的两个重要概念,它们用于保证数据的一致性和完整性。下面是这两个概念的详细说明和使用示例:
1. DataSourceTransactionManager
DataSourceTransactionManager
是 Spring 提供的一个事务管理器,用于管理基于 JDBC 数据源的事务。它使用一个底层的 DataSource
(数据库连接池)来进行事务管理,并确保在事务提交或回滚时正确处理数据库连接。
使用方法:
首先,你需要配置一个 DataSource
和一个 DataSourceTransactionManager
。典型的步骤如下:
@Configuration
@EnableTransactionManagement
public class AppConfig {
@Bean
public DataSource dataSource() {
// 配置你的数据源,比如使用 HikariCP 或其他连接池
return DataSourceBuilder.create()
.url("jdbc:mysql://localhost:3306/yourdb")
.username("root")
.password("password")
.driverClassName("com.mysql.cj.jdbc.Driver")
.build();
}
@Bean
public DataSourceTransactionManager transactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
}
在上面的配置中:
dataSource
:配置数据库的连接池。transactionManager
:创建DataSourceTransactionManager
,并将其绑定到dataSource
。
2. @Transactional
注解
@Transactional
是 Spring 提供的一个注解,用于声明事务管理,它简化了事务管理的配置。你可以在类或方法上使用该注解来指定哪些方法需要事务管理。Spring 会自动为这些方法创建代理,在方法执行时启动一个事务,方法执行完毕后提交或回滚事务。
使用方法:
@Transactional
注解可以应用于类或方法上。它的常见配置如下:
- 类级别:事务会应用于该类中的所有方法。
- 方法级别:事务会仅应用于指定的方法。
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
// 在方法上加 @Transactional,表示此方法需要事务管理
@Transactional
public void createUser(User user) {
userRepository.save(user);
// 这里可以添加更多的业务逻辑,如果在此过程中发生异常,事务会回滚
}
// 可以选择不同的事务配置,如传播行为、隔离级别等
@Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED)
public void updateUser(User user) {
userRepository.update(user);
}
}
在上面的代码中:
@Transactional
:标明方法createUser
需要事务管理,执行过程中如果发生任何异常,Spring 会自动回滚事务。- 你可以通过
propagation
和isolation
属性来配置事务的传播行为和隔离级别。例如,Propagation.REQUIRED
表示如果当前有事务,则加入当前事务;Isolation.READ_COMMITTED
表示使用“读已提交”隔离级别。
3. 事务的传播行为(Propagation
)
Spring 提供了七种传播行为来定义事务的传播方式:
REQUIRED
:如果当前方法有事务,则加入该事务;如果没有事务,则新建一个事务。REQUIRES_NEW
:每次方法调用都会启动一个新的事务,独立于调用它的事务。SUPPORTS
:如果当前方法有事务,则加入该事务;如果没有事务,则以非事务方式执行。NOT_SUPPORTED
:当前方法不支持事务,如果有事务,则挂起当前事务。MANDATORY
:当前方法必须在事务中执行,如果没有事务,则抛出异常。NEVER
:当前方法不能在事务中执行,如果有事务,则抛出异常。NESTED
:如果当前方法有事务,则在当前事务中启动一个嵌套事务,否则与REQUIRED
一样创建一个新的事务。
4. 事务的隔离级别(Isolation
)
事务的隔离级别决定了事务间的可见性,Spring 提供了以下几种隔离级别:
READ_UNCOMMITTED
:最低的隔离级别,允许脏读。READ_COMMITTED
:允许不可重复读,但不允许脏读。REPEATABLE_READ
:允许不可重复读,但不允许脏读和幻读。
5. @Transactional
配置示例
@Transactional(
propagation = Propagation.REQUIRED,
isolation = Isolation.READ_COMMITTED,
rollbackFor = {SQLException.class, SomeSpecificException.class}
)
public void transferMoney(Account fromAccount, Account toAccount, BigDecimal amount) {
fromAccount.withdraw(amount);
toAccount.deposit(amount);
}
在上面的代码中:
propagation = Propagation.REQUIRED
:如果当前有事务,加入该事务;如果没有,则创建新的事务。isolation = Isolation.READ_COMMITTED
:使用“读已提交”隔离级别,避免脏读。rollbackFor
:指定哪些异常会触发事务回滚,这里设置了对SQLException
和自定义异常SomeSpecificException
的回滚。
6. 总结
DataSourceTransactionManager
是 Spring 用于基于 JDBC 数据源的事务管理器,通常在需要进行低级事务管理时使用。@Transactional
注解是 Spring 提供的事务声明式管理工具,能够简化事务管理的配置。它可以根据需要控制事务的传播行为、隔离级别、回滚规则等。
一般情况下,推荐使用 @Transactional
注解来管理事务,因为它更加简洁和易于维护,而 DataSourceTransactionManager
通常用于程序员需要更细粒度控制事务时。