2024年3月14日发(作者:)
开发人员、设计人员和架构师经常会混淆
事务模型
与
事务策略
。我经常会让与
客户接触的架构师和技术总监描述他们项目的事务策略。我通常会获得三种回应。
有时,他们会说 “我们实际上并未在应用程序中使用事务。”另一些时候,我
会听到迷惑的回答:“我不明白你的意思。”但是,我也会遇到非常自信的回答:
“我们使用声明式事务。”在本文中,术语
声明式事务
描述的是一个事务
模型
,
但它绝不是一种事务
策略
。
关于本系列
事务将改善您数据的质量、完整性以及一致性,并且让您的应用程序更加可靠。
在 Java 应用程序中实现成功的事务处理并不是一项轻松的任务,它是一项与编
写代码相关的设计工作。 在这个新的 系列 中,Mark Richards 将指导您设计
一个有效的事务策略,它适用于各种用例,从简单的应用程序到高级性能事务处
理。
Java 平台支持的三种事务模型包括:
Local Transaction 模型
Programmatic Transaction 模型
Declarative Transaction 模型
这些模型描述事务在 Java 平台中的基本运行方式,以及它们是如何实现的。但
是,它们仅提供了事务处理的规则和语义。如何应用事务模型则完全由您决定。
举例来说,应该如何在 REQUIRED 和 MANDATORY 事务属性之间做出选择?您应
该在何时何种情况下指定事务回滚指令?您应该在何时考虑 Programmatic
Transaction 模型与 Declarative Transaction 模型的优劣?您应该如何优化
高性能系统的事务?事务模型本身无法回答这些问题。您必须通过开发自己的事
务策略或采用本文介绍的四种主要事务策略之一来解决它们。
如本系列的 第一篇文章 所述,许多常见的事务陷阱都会影响到事务行为,并且
由此会降低数据的完整性和一致性。同样,缺乏有效的(或任何)事务策略将对
您数据的完整性和一致性造成负面影响。本文所描述的事务模型是开发有效事务
策略的基本元素。理解这些模型之间的差异以及它们的运行方式对于理解使用它
们的事务策略非常重要。在介绍完三种事务模型之后,我将讨论适用于大多数业
务应用程序(从简单的 Web 应用程序到大型的高速事务处理系统)的四种事务
策略。
事务策略
系列的后续文章将详细讨论这些策略。
Local Transaction 模型
在 Local Transaction 模型中,事务由底层数据库资源管理程序(而非应用程
序所在的容器或框架)管理,这便是它得名的原因。在这个模型中,您将管理
连
接
,而不是
事务
。从 “了解事务陷阱” 一文可知,在使用对象关系映射框架,
如 Hibernate、TopLink 或 the Java Persistence API (JPA),执行数据库更
新时,您不能使用 Local Transaction 模型。在使用数据访问对象(DAO)或基
于 JDBC 的框架和数据库存储过程时,您可以使用它。
您可以采用以下两种方式来使用 Local Transaction 模型:让数据库来管理连
接,或者以编程的方式管理连接。要让数据库管理连接,您需要将 JDBC
Connection 对象上的 autoCommit 属性设置为 true(默认值),这将通知底层
数据库管理系统(DBMS)在完成插入、更新或删除操作之后提交事务,或者在操
作失败时返回任务。清单 1 展示了这种技巧,它在 TRADE 表中插入了一条股票
交易命令:
清单 1. 包括一个更新的本地事务
public class TradingServiceImpl {
public void processTrade(TradeData trade) throws Exception {
Connection dbConnection = null;
try {
DataSource ds = (DataSource)
(new InitialContext()).lookup("jdbc/MasterDS");
dbConnection = nection();
oCommit(true);
Statement sql = Statement();
String stmt = "insert into TRADE ...";
eUpdate(stmt1);
} finally {
if (dbConnection != null)
();
}
}
}
注意,在清单 1 中,autoCommit 值设置为 true,这将指示 DBMS 应该在各数
据库语句之后提交本地事务。如果在逻辑工作单元(LUW)中维护一个数据库活
动,那么这一技巧将非常有用。但是,假设清单 1 中的 processTrade() 方法
还将更新 ACCT 表中的余额以反映交易订单的值。在本例中,两个数据库操作是
相互独立的,针对 TRADE 表的插入操作将在更新 ACCT 表之后提交给数据库。
若 ACCT 表更新失败,没有任何机制可以回滚到对 TRADE 表的更新操作,从而
造成数据库中的数据不一致。
此场景又引出了第二个技巧:以编程的方式管理连接。在此技巧中,您将
Connection 对象上的 autoCommit 属性设置为 false,并手动提交或回滚连接。
清单 2 演示了此技巧:


发布评论