Java 事务设计策略

2017/12/5 posted in  Java Base

前几天看 Spring 事务相关的资料,发现了《Java 事务设计策略》一书,所以总结一下。

这篇文章主要讲事务背后的一些理论知识,代码次之,主要是为了让读者知其所以然。

事务模型

本地事务模型(Local Transaction Model)

在这个模型中,开发人员管理连接,而不是事务。实际上是数据库管理本地事务。

public void updateTradeOrder(TradeOrderData order) throws Exception {
    DataSource ds = null;
    Connection conn = ds.getConnection();
    conn.setAutoCommit(false);
    Statement stmt = conn.createStatement();
    String sql = "update trade_order ... ";
    try {
        stmt.executeUpdate(sql);
        conn.commit();
    } catch (Exception e) {
        conn.rollback();
        throw e;
    } finally {
        stmt.close();
        conn.close();
    }
}

编程式事务模型(Programmatic Transaction Model)

在这个模型中,开发者管理事务,而不是连接。Spring 框架提供了 TransactionTemplate 类用于编程式事务的管理。

public void updateTradeOrder(TradeOrderData order) throws Exception {
    transactionTemplate.execute(new TransactionCallback() {
        public Object doInTransaction(TransactionStatus status) {
            try {
                dao.updateTradeOrder(order);
            } catch (Exception e) {
                status.setRollbackOnly();
                throw e;
            }
        }
    });
}

声明式事务模型(Declarative Transaction Model)

在这个模型中,框架或者容器管理事务的开始和结束(比如,提交或者回滚)。开发人员只需要告诉框架当程序发生异常什么时候回滚事务,以及在配置文件中配置事务(比如 Spring 的 ApplicationContext.xml)。

@Transactional(propagation = Propagation.REQUIRED)
public void updateTradeOrder(TradeOrderData order){
    dao.updateTradeOrder(order);
}

JTA 和 JTS

Java Transaction API (JTA)

JTA 是开发人员用来管理事务的接口。

Java Transaction Service (JTS)

JTS 是实现了 JTA 的底层事务服务,而且应用于大多数的商业和开源的服务器(请注意除了 JTS 之外,市场上还有其他可用的事务服务)。

JTA 和 JTS 的关系就像 JDBC 和 相关的数据库驱动一样。JTA 就像 JDBC,JTS 就像数据库驱动。比如有 MySQL 数据库驱动,Oracle 数据库驱动,都遵守了 JDBC 规范。

事务设计模式

客户端拥有事务设计模式(Client Owner Transaction Design Pattern)

顾名思义,在这个事务设计模式中,客户端委托组件拥有事务。

当 domain services 过于细化,并且不存在聚合服务时,就会发生这种情况。当这种情况发生的时候,我们需要将事务管理推送到表示层来维护 ACID 属性。

Domain Service 拥有事务设计模式(Domain Service Owner Transaction Design Pattern)

Domain Service 拥有事务设计模式是最常用的事务设计模式,而且应用于大部分基于 java 的程序架构中。在这个模式中,Domain Service 组件拥有事务和相关的事务管理。

在 Spring 中,Domain Service 组件被实现为POJO,同时也使用声明式事务管理。

服务端拥有事务设计模式(Server Delegate Owner Transaction Design Pattern)

当在程序架构中使用命令模式或者服务端委托设计模式时,这个事务设计模式最适用。在这个模式中,服务端委托组件拥有事务以及负责全部事务的管理。

  • 命令模式

    这种模式背后的基本原理是客户端功能被放置在一个命令中并发送到服务端执行。

  • 服务端委托设计模式

    此模式只是将客户端业务代理逻辑放置在服务端上的基于服务端的委托对象中。

服务端拥有事务设计模式 是 Domain Service 拥有事务设计模式 的特例。

当使用命令模式时,服务端委托组件被实现为一个单一的命令处理器组件,它定位到相应的命令实现对象并执行命令。

使用服务端委托设计模式时,每个客户端请求的功能组将作为单独的服务端委托实现。

总结

在开发中,我们主要使用 声明式事务模型Domain Service 拥有事务设计模式

参考资料