主表 bylaw (ID, 標題, 作者...);子表 bylaw_content (正文) 、bylaw_affix (附件) 皆以 bylaw_id 關聯。刪除一筆主記錄需同步刪除三表,否則產生孤兒資料。
public int deleteBylaw(int id) {
DataSource ds = ...; // 連接池
Connection conn = null;
try {
conn = ds.getConnection();
conn.setAutoCommit(false); // 關閉自動提交,開啟事務
try (PreparedStatement ps1 = conn.prepareStatement("DELETE FROM bylaw WHERE ID=?")) {
ps1.setInt(1, id);
ps1.executeUpdate();
}
try (PreparedStatement ps2 = conn.prepareStatement("DELETE FROM bylaw_content WHERE bylaw_id=?")) {
ps2.setInt(1, id);
ps2.executeUpdate();
}
try (PreparedStatement ps3 = conn.prepareStatement("DELETE FROM bylaw_affix WHERE bylaw_id=?")) {
ps3.setInt(1, id);
ps3.executeUpdate();
}
conn.commit(); // 全部成功提交
return 1;
} catch (SQLException e) {
if (conn != null) try { conn.rollback(); } catch (SQLException ignored) {}
log.error("刪除失敗,已回滾", e);
return -1;
} finally {
if (conn != null) try { conn.setAutoCommit(true); conn.close(); } catch (SQLException ignored) {}
}
}
適用場景:單一資料來源、單一 JVM 內的多條 SQL 原子操作。缺點:無法跨多個資料庫、跨 JVM、或整合 JMS 訊息發送等非資料庫資源。
@Stateless
@TransactionManagement(TransactionManagementType.CONTAINER) // CMT 容器管理事務
public class BylawServiceBean implements BylawService {
@Resource DataSource ds;
@Resource SessionContext ctx; // 注入 SessionContext 取得 UserTransaction
public int deleteBylaw(int id) {
UserTransaction utx = ctx.getUserTransaction();
Connection conn = null;
try {
utx.begin(); // 開啟 JTA 事務
conn = ds.getConnection();
// 同樣的三條 DELETE,此處省略 PreparedStatement 代碼
// ...
utx.commit(); // 提交分散式事務
return 1;
} catch (Exception e) {
try { utx.rollback(); } catch (Exception ignored) {}
log.error("JTA 事務回滾", e);
return -1;
} finally {
if (conn != null) try { conn.close(); } catch (SQLException ignored) {}
}
}
}
JTA 關鍵介面:
UserTransaction:應用程式層控制事務邊界 (begin/commit/rollback)。TransactionManager:容器/應用伺服器內部管理事務上下文、掛起/恢復。Transaction:代表具體事務實例,可註冊同步回調、查詢狀態。適用場景:跨多個資料源 (Oracle + MySQL)、資料庫 + JMS、多個 EJB 模組、微服務協同 (配合 JTS/OTS)。
| 維度 | JDBC 本地事務 | JTA 分散式事務 |
|---|---|---|
| 資料源數量 | 單一 | 多個 (XA 支援) |
| 部署環境 | 任意 (含 Servlet 容器) | 需支援 JTA 的應用伺服器 |
| 效能 | 高 (無協調器開銷) | 較低 (兩階段提交 2PC) |
| 程式設計模型 | 手動控制 Connection | 聲明式 (CMT) 或程式化 (BMT) |
| 非資料庫資源 | 不支援 | 支援 (JCA、JMS) |