SqlSession session = sqlSessionFactory.openSession(false); // false = 非自動提交
try {
UserMapper mapper = session.getMapper(UserMapper.class);
mapper.update(user1);
mapper.update(user2);
int i = 1 / 0; // 模擬異常
session.commit(); // 全部成功才提交
} finally {
session.close(); // 關閉釋放連接
}
核心:openSession(false) 開啟事務,commit()/rollback()(異常時隱式回滾),close() 釋放。
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
@Transactional@Service
public class UserService {
@Autowired UserMapper mapper;
@Transactional // 默認:RuntimeException/Error 觸發回滾
public void batchUpdate() {
mapper.update(user1);
int i = 1 / 0; // 拋出 RuntimeException → 事務回滾
mapper.update(user2); // 不會執行
}
}
注意:捕獲異常且不重新拋出會導致事務提交(框架感知不到異常)。
@Autowired TransactionTemplate txTemplate;
public void batchWithTemplate() {
txTemplate.execute(status -> {
mapper.update(user1);
int i = 1 / 0; // 異常 → 回滾
mapper.update(user2);
return null;
});
}
<tx:jta-transaction-manager/>
// 或指定 ManagedTransactionFactory
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="transactionFactoryClass" value="org.apache.ibatis.transaction.managed.ManagedTransactionFactory"/>
</bean>
| 傳播類型 | 行為 | 常用場景 |
|---|---|---|
| REQUIRED | 有事務則加入,無則新建 | 默認,大多數業務 |
| REQUIRES_NEW | 掛起當前,新建獨立事務 | 日誌記錄、獨立補償 |
| NESTED | 嵌套事務(保存點) | 部分回滾 |
| SUPPORTS | 有事務則加入,無則非事務 | 只讀查詢 |
| NOT_SUPPORTED | 掛起事務,非事務運行 | 外部服務調用 |
| NEVER | 不允許事務,拋異常 | 嚴格非事務 |
| MANDATORY | 必須在事務中,否則拋異常 | 強制事務上下文 |
| 隔離級別 | 髒讀 | 不可重複讀 | 幻讀 |
|---|---|---|---|
| READ_UNCOMMITTED | ✅ | ✅ | ✅ |
| READ_COMMITTED | ❌ | ✅ | ✅ |
| REPEATABLE_READ | ❌ | ❌ | ✅ |
| SERIALIZABLE | ❌ | ❌ | ❌ |
MySQL InnoDB 默認 REPEATABLE_READ(通過 MVCC + Gap Lock 解決幻讀)。
@Transactional,DAO 層不加。throw new RuntimeException(e)),切勿吞掉。@Transactional(readOnly = true) 優化。MyBatis 事務管理核心在於 SqlSession 生命週期與 Spring 事務抽象的結合。理解 @Transactional 底層原理(AOP 代理、ThreadLocal 綁定連接、異常攔截回滾),才能在複雜業務中正確控制事務邊界。