企業級應用常面臨多異構數據庫共存挑戰:邏輯模型異構 (關系/對象/層次)、物理模型異構 (Oracle/Sybase/DB2)、作業系統異構 (Unix/Windows)、硬體平台異構、網絡拓撲異構。本文研究基於 Java 技術棧的多數據庫統一訪問與數據交換解決方案,對比 JavaBean 與 EJB 兩代架構演進。
| 異構類型 | 具體表現 | 解決難度 |
|---|---|---|
| 邏輯數據模型 | 層次/網狀/關系/對象-關系/對象 | 高 (需模型映射層) |
| 物理數據模型 | 存儲結構、索引、分區差異 (同為關系庫) | 中 (JDBC 屏蔽大部分) |
| 作業系統 | Unix/Linux/Windows/macOS/OS/2 | 低 (Java 跨平台特性) |
| 硬體平台 | 大型機/小型機/工作站/PC/手持設備 | 低 (JVM 屏蔽) |
| 網絡拓撲 | LAN/WAN/以太網/令牌環/光纖通道 | 低 (TCP/IP 標準) |
核心突破口:關系模型下的跨 OS、跨 DBMS 統一訪問 —— 正是 Java JDBC + 跨平台特性的最佳應用場景。
// JavaBean 封裝單庫操作
public class DatabaseConnectBean {
private Connection conn;
private String url, user, password, driver;
public void connect() throws SQLException, ClassNotFoundException {
Class.forName(driver);
conn = DriverManager.getConnection(url, user, password);
}
public ResultSet query(String sql) throws SQLException {
return conn.createStatement().executeQuery(sql);
}
public int update(String sql) throws SQLException {
return conn.createStatement().executeUpdate(sql);
}
// 多線程同步鎖保護共享連接 (簡易版)
public synchronized void executeInTransaction(Runnable task) {
try {
conn.setAutoCommit(false);
task.run();
conn.commit();
} catch (Exception e) {
conn.rollback();
throw new RuntimeException(e);
} finally {
conn.setAutoCommit(true);
}
}
}
// Servlet 協調多 Bean
public class MultiDBServlet extends HttpServlet {
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// 實例化不同數據庫的 Bean
DatabaseConnectBean oracleBean = new DatabaseConnectBean(oracleProps);
DatabaseConnectBean sybaseBean = new DatabaseConnectBean(sybaseProps);
DatabaseConnectBean db2Bean = new DatabaseConnectBean(db2Props);
try {
oracleBean.connect(); sybaseBean.connect(); db2Bean.connect();
// 業務邏輯:跨庫查詢、數據同步、異構聯接
// 缺點:事務無法跨 Bean 原子提交
} catch (Exception e) {
throw new ServletException("多庫操作失敗", e);
} finally {
closeQuietly(oracleBean, sybaseBean, db2Bean);
}
}
}
| 服務 | 容器職責 | 開發者受益 |
|---|---|---|
| 遠程訪問 | RMI-IIOP 代理、序列化、網絡通訊 | 透明分布式調用 |
| 安全性 | 認證/授權/聲明式安全 (deployment descriptor) | 零代碼安全控制 |
| 持久化 | Entity Bean CMP/BMP、JDO/JPA 整合 | ORM 映射標準化 |
| 事務管理 | JTA 兩階段提交、聲明式事務屬性 | 跨資源原子操作 |
| 並發控制 | 實例池化、同步化、鎖定策略 | 高併發無鎖編程 |
| 資源管理 | DataSource/JMS/JCA 統一 JNDI 查找 | 配置與代碼分離 |
public class MultiDBSessionBean implements SessionBean {
private SessionContext ctx;
private DataSource oracleDS, sybaseDS, db2DS;
public void ejbCreate() {
try {
InitialContext ic = new InitialContext();
oracleDS = (DataSource) ic.lookup("jdbc/OracleDS");
sybaseDS = (DataSource) ic.lookup("jdbc/SybaseDS");
db2DS = (DataSource) ic.lookup("jdbc/DB2DS");
} catch (NamingException e) {
throw new EJBException(e);
}
}
// 容器管理事務 (CMT) - 聲明式
public void syncCustomerData(String custId) {
Connection oraConn = null, sybConn = null, db2Conn = null;
try {
oraConn = oracleDS.getConnection(); // 參與全域事務
sybConn = sybaseDS.getConnection();
db2Conn = db2DS.getConnection();
// 三庫同步更新客戶資料
updateOracle(oraConn, custId);
updateSybase(sybConn, custId);
updateDB2(db2Conn, custId);
// 容器自動提交/回滾 (兩階段提交)
} catch (SQLException e) {
ctx.setRollbackOnly(); // 標記回滾
throw new EJBException("跨庫同步失敗", e);
} finally {
closeQuietly(oraConn, sybConn, db2Conn);
}
}
// 回調方法
public void setSessionContext(SessionContext ctx) { this.ctx = ctx; }
public void ejbRemove() {} public void ejbActivate() {} public void ejbPassivate() {}
}
<assembly-descriptor>
<container-transaction>
<method>
<ejb-name>MultiDBSessionBean</ejb-name>
<method-name>syncCustomerData</method-name>
</method>
<trans-attribute>Required</trans-attribute>
</container-transaction>
</assembly-descriptor>
| 評估維度 | JavaBean + Servlet | EJB (CMT/BMT) |
|---|---|---|
| 跨庫事務一致性 | ❌ 不支援 | ✅ JTA 兩階段提交 |
| 連接池管理 | ❌ 手工實現 | ✅ 容器級 DataSource 池 |
| 分布式部署 | ❌ 單點 Web 容器 | ✅ 叢集/負載均衡/故障轉移 |
| 安全整合 | ❌ 自行實現 | ✅ JAAS/聲明式角色權限 |
| 開發複雜度 | ✅ 低 (POJO) | ⚠️ 中高 (介面/描述符/容器) |
| 測試便利性 | ✅ 易單元測試 | ⚠️ 需容器/嵌入式 EJB 容器 |
| 適用場景 | 簡單跨庫查詢、唯讀報表、非關鍵同步 | 核心業務、財務/訂單/庫存強一致性場景 |
EJB 2.x 複雜度導致 Spring 崛起,現代最佳實踐:
@Transactional 聲明式事務 + JtaTransactionManager 整合 Atomikos/Bitronix 實現無應用服務器分布式事務@Stateless + @TransactionAttribute,無需描述符從 JavaBean 到 EJB,是從「手工拼裝」走向「容器托管企業級服務」的架構演進。雖然 EJB 早期版本因重量級被詬病,但其核心價值——聲明式分布式事務、統一資源管理、安全整合、叢集透明——至今仍是關鍵業務系統不可替代的基石。現代技術棧 (Spring/Jakarta EE) 以輕量化方式繼承並發揚了這些核心能力,開發者應根據業務一致性要求、團隊技術棧、部署環境選擇最適架構。