事务管理集成
Spring 事务管理器与 MyBatis 集成后,可通过声明式方式统一管理数据库操作的事务边界。
DataSourceTransactionManager 配置
Spring 提供的平台事务管理器,用于管理基于 JDBC 的事务。
Java Config
Java
@Configuration
@EnableTransactionManagement
public class TransactionConfig {
@Bean
public DataSourceTransactionManager transactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
}
XML 配置
XML
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 启用注解驱动事务 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
事务传播行为
| 传播行为 | 说明 | 场景 |
|---|---|---|
| REQUIRED | 默认,有事务则加入,无则新建 | 大多数业务场景 |
| REQUIRES_NEW | 总是新建事务,挂起当前事务 | 日志记录、审计 |
| NESTED | 嵌套事务,可部分回滚 | 复杂业务流程 |
| SUPPORTS | 有事务则加入,无则非事务执行 | 查询方法 |
| NOT_SUPPORTED | 非事务执行,挂起当前事务 | 批量操作 |
| MANDATORY | 必须在事务中,否则抛异常 | 强制事务场景 |
| NEVER | 必须非事务执行,有事务则抛异常 | 特殊要求 |
Java
// 默认传播行为
@Transactional
public void createUser(User user) {
userMapper.insert(user);
}
// 独立事务
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void logOperation(String message) {
logMapper.insert(message);
}
回滚规则
默认只回滚 RuntimeException 和 Error,通过 rollbackFor 可自定义。
Java
// 回滚所有异常
@Transactional(rollbackFor = Exception.class)
public void processOrder(Order order) {
orderMapper.insert(order);
// 可能抛出 BusinessException
validateOrder(order);
}
// 指定回滚多个异常
@Transactional(rollbackFor = {SQLException.class, IOException.class})
public void batchUpdate(List<Data> list) { }
// 排除特定异常不回滚
@Transactional(noRollbackFor = BusinessException.class)
public void syncData() { }
事务隔离级别
| 隔离级别 | 脏读 | 不可重复读 | 幻读 |
|---|---|---|---|
| READ_UNCOMMITTED | 可能 | 可能 | 可能 |
| READ_COMMITTED | 不 | 可能 | 可能 |
| REPEATABLE_READ | 不 | 不 | 可能 |
| SERIALIZABLE | 不 | 不 | 不 |
Java
@Transactional(isolation = Isolation.READ_COMMITTED)
public List<User> findUsers() {
return userMapper.selectAll();
}
// 使用数据库默认
@Transactional(isolation = Isolation.DEFAULT)
public void updateUser(User user) { }
超时与只读事务
Java
// 超时设置(秒)
@Transactional(timeout = 30)
public void batchProcess(List<Data> list) { }
// 只读事务(优化查询性能)
@Transactional(readOnly = true)
public User findById(Long id) {
return userMapper.selectById(id);
}
readOnly = true 不仅用于优化,某些数据库驱动会据此获取只读连接,提升并发性能。
事务管理器与 MyBatis 集成原理
Java
@Transactional
|
v
TransactionInterceptor (AOP 拦截器)
|
v
DataSourceTransactionManager
|
v
TransactionSynchronizationManager (绑定 Connection 到当前线程)
|
v
MyBatis SqlSession (从 DataSource 获取已绑定事务的 Connection)
|
v
Mapper 方法执行
MyBatis 的 SqlSession 通过 SpringManagedTransaction 获取事务管理器绑定的 Connection,确保在同一事务内使用同一连接。
多事务管理器
Java
@Configuration
@EnableTransactionManagement
public class MultiTxConfig {
@Bean("primaryTx")
@Primary
public PlatformTransactionManager primaryTxManager(
@Qualifier("primaryDataSource") DataSource ds) {
return new DataSourceTransactionManager(ds);
}
@Bean("secondaryTx")
public PlatformTransactionManager secondaryTxManager(
@Qualifier("secondaryDataSource") DataSource ds) {
return new DataSourceTransactionManager(ds);
}
}
// 指定事务管理器
@Transactional("secondaryTx")
public void saveToSecondary(Data data) { }
事务失效场景
text
@Service
public class OrderService {
// 自调用不走代理,事务失效
public void createOrder() {
this.saveOrder(); // 事务不生效
}
@Transactional
public void saveOrder() { }
// 非 public 方法,事务失效
@Transactional
protected void internalMethod() { }
}
要点总结
- 通过 @EnableTransactionManagement 启用注解驱动事务
- DataSourceTransactionManager 管理 JDBC 事务,与 MyBatis 无缝集成
- 默认只回滚 RuntimeException 和 Error,需 rollbackFor 指定全异常回滚
- 传播行为控制事务边界,REQUIRES_NEW 用于独立事务
- 只读事务 readOnly = true 可优化查询性能
- 自调用和非 public 方法导致事务失效
- 多事务管理器需通过 value 属性指定
📝 发现内容有误?点击此处直接编辑