事務是數據一致性的守護者。本文從 ACID 原則出發,梳理 Java 事務的三大類型——JDBC、JTA、容器事務,幫你建立完整知識體系。
事務是一組不可分割的操作單元,滿足 ACID 四大特性:
通俗理解:銀行轉賬,扣款與入賬必須同時成功或同時失敗。
解決數據安全訪問問題。無事務時,網絡中斷導致扣款成功但入賬失敗,數據即不一致。事務將相關操作綁定為整體,保證業務邏輯正確性。
基於 Connection 對象控制:
Connection conn = dataSource.getConnection();
conn.setAutoCommit(false); // 關閉自動提交
try {
// 多條 SQL 操作
stmt1.executeUpdate(sql1);
stmt2.executeUpdate(sql2);
conn.commit(); // 統一提交
} catch (Exception e) {
conn.rollback(); // 回滾
} finally {
conn.setAutoCommit(true);
conn.close();
}
局限:無法跨多個數據庫/資源管理器。
Java Transaction API,支持跨多個資源(數據庫、消息隊列等)的全局事務。核心接口:
UserTransaction:應用程序邊界控制(begin/commit/rollback)TransactionManager:容器/框架級事務管理XAResource:資源管理器適配 XA 協議(兩階段提交)典型流程:TM 協調多個 RM(資源管理器)執行 準備 → 提交/回滾 兩階段。
EJB 容器或 Spring 框架通過 AOP 代理,將事務邊界與業務代碼分離:
@Transactional(rollbackFor = Exception.class)
public void transfer(Account from, Account to, BigDecimal amount) {
from.debit(amount);
to.credit(amount);
// 拋出異常自動回滾
}
核心屬性:傳播行為、隔離級別、超時、只讀、回滾規則。
| 隔離級別 | 臟讀 | 不可重複讀 | 幻讀 | 性能 |
|---|---|---|---|---|
| READ_UNCOMMITTED | √ | √ | √ | 最高 |
| READ_COMMITTED | × | √ | √ | 高 |
| REPEATABLE_READ | × | × | √ | 中 |
| SERIALIZABLE | × | × | × | 最低 |
MySQL InnoDB 默認 REPEATABLE_READ,Oracle/PostgreSQL 默認 READ_COMMITTED。
REQUIRED(默認):有事務加入,無則新建REQUIRES_NEW:掛起當前事務,強制新建獨立事務NESTED:嵌套事務,外層回滾內層必回滾,內層回滾外層可選擇提交SUPPORTS / NOT_SUPPORTED / MANDATORY / NEVER理解事務本質,選對事務類型,配好隔離級別與傳播行為,是寫出高可靠業務代碼的關鍵。實戰中優先使用 Spring 聲明式事務,分布式場景引入 Seata/Atomikos 等 JTA 實現。