新專案採用 Spring Boot 簡化配置,持久層用 MyBatis,@Transactional 註解管理事務,測試發現例外拋出時資料未回滾。經排查發現並非框架配置錯誤,而是**資料表儲存引擎為 MyISAM**,該引擎**不支援交易**,導致事務管理器無法生效。
@TransactionalRuntimeException-- 檢查表引擎
SHOW CREATE TABLE your_table;
-- 結果顯示: ENGINE=MyISAM
MyISAM 特性:表級鎖、不支援交易、不支援外鍵、全文索引 (5.6 前)
InnoDB 特性:列級鎖、支援 ACID 交易、支援外鍵、MVCC、崩潰恢復
ALTER TABLE your_table ENGINE=InnoDB;
CREATE TABLE t (
id INT PRIMARY KEY AUTO_INCREMENT,
...
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
[mysqld]
default-storage-engine=InnoDB
@Service
public class OrderService {
@Autowired OrderMapper orderMapper;
@Transactional(rollbackFor = Exception.class) // 建議明確指定回滾異常
public void createOrder(Order order) {
orderMapper.insert(order);
// 模擬業務異常
if (true) throw new RuntimeException("故意失敗");
}
}
再次測試,資料應正確回滾。
@Transactional 是否在 public 方法上 (私有/protected 不生效)DataSourceTransactionManager@Transactional (由 Service 層控制)教訓總結: 框架配置再完美,若底層資料庫引擎不支援交易,事務永遠不會生效。建立資料表時**預設指定 InnoDB** 應成肌肉記憶。