当客户在网上商店购买商品时,您希望您的订单能够被快速处理和交付。 作为银行客户,您要确保转账期间钱不会神秘地消失。 在企业应用程序中,经典事务保证了诸如一致性和与其他事务的隔离之类的质量。 分布式事务可跨多种资源(例如,您的商店数据库和企业资源计划(ERP)系统)提供此类保证。 事务质量通常由您的中间件基础结构提供,并且可以使普通程序员的工作更轻松。
但是,在云中,中间件通常不能保证这种质量。 分布式事务通常不可用,而同时基础架构可能更加不稳定。 甚至很小的错误率也可以Swift扩展您的应用程序并导致可观的支持成本,因此,避免或适当地处理可伸缩的云应用程序中可能的事务管理错误至关重要。
在这个由两部分组成的系列的第1部分中,我提供了一些有关事务处理的背景知识,即事务保证的质量,并且我研究了云设置中的不同之处。 在第2部分中 ,我将展示用于调用非事务服务的经典事务处理的替代方法。
“交易的主要属性是其原子性。 在实际的分布式事务中,这可能无法完全实现,因此一致性也可能被破坏。 ”
交易的一般性质
在IT世界中,交易通常被认为是对信息的单独操作,必须作为一个完整的单元来进行成功或失败。 事务永远不能部分完成。 这是重要的属性。 例如,财务操作依赖于交易的总金额不会改变:如果您从一个帐户中取钱,则需要确保将钱同时存入另一个帐户。
更正式地讲,事务通常与四个“ ACID”属性相关联:
- 原子性 -交易只能是“全部或全部”。 如果成功,则将执行事务中的所有操作。 如果失败,则不执行任何操作。
- 一致性 —事务必须使系统从一个一致状态进入另一个一致状态。 例如,任何写入数据库的数据都必须服从数据库中定义的所有约束(提交时)。
- 隔离 -多个并发事务彼此隔离,因为它们的行为就像顺序执行一样。
- 耐用性 —提交事务后,即使在断电或其他错误的情况下,事务的结果也可以保留。
尽管这些是交易的理论原理,但在现实世界中,某些效果和优化可能会为了性能而改变这些原理。
例如,虽然原子性,一致性和持久性是事务处理系统中的重要目标,但由于严格隔离对性能的潜在影响,隔离通常会更加宽松。 已经定义了不同的事务隔离级别,以确定系统中允许哪些隔离失败。 这些隔离级别出现在单个数据库中,因此在此我们不再关注该主题。
事务通常由调用资源管理器 (通常是数据库或消息队列)的事务客户端发起。 资源管理器管理资源,例如数据库表或数据库中的行。 客户端打开一个事务,并可能通过多个调用在尝试提交该事务之前对系统中的一个或多个资源执行许多操作(请参见图1)。 当事务中只有一个资源管理器时,它可以自行决定事务在原子性和一致性方面是否正确,并且可以在提交时确保持久性。
图1.与客户端,资源管理器和资源的典型事务
自动提交
上面的讨论使用了start()
和commit()
操作的显式事务划分,因此可以将对一个资源的多个操作分组为一个原子更改。 在交易期间,受影响的资源被锁定以防止其他更改。 然后,是否提交还是回滚的决定也可以取决于其他操作的结果以及可能其他资源的结果。
当事务客户端需要对资源执行单个操作时,无需涉及对资源管理器的多次调用。 可以自动提交对单个资源的单个更改-即,该更改立即生效,如图2所示。
图2.显式提交允许等待其他操作的结果,但是锁定资源
如下所述,针对单个资源自动提交还是使用显式提交或回滚的决定在用于多种资源更改的错误处理模式中也起作用。
长期交易与短期交易
上述交易属性在一般意义上对交易有效。 例如,即使对于使用信用卡购买的商业交易,您也希望保留这些属性。 但是,某些事务可能需要很长时间。 例如,当您入住酒店时,酒店通常会以电子方式查询您的帐户中是否有足够的钱(即卡上的限额)。 但是,要等到几天后退房,才可能向帐户收取费用。 这些被称为长时间运行的事务—通常将业务事务分解为多个技术事务,以避免阻塞事务和资源管理器中的(技术)资源。
请注意,资源管理器通常无法跨技术事务锁定资源。 为了使长时间运行的业务事务能够锁定资源,通常需要对功能数据模型进行调整以存储此资源的额外状态。
例如,当客户入住酒店时,短暂的技术交易会在他们的帐户上保留一些金额。 预订的状态可以存储在数据库的单独行中,并且在预订时,确认合并的预订没有超过客户的信用额度。 在结帐时,另一笔短暂的技术交易会将预订与实际的汇款交换。 每个技术交易都可以(在上述隔离级别的限制内)满足ACID属性,但业务交易则不能。 保留的资金与其他交易没有隔离,因为其他业务交易无法保留。
可以使用特殊技术来确保长时间运行的业务交易中的原子性和一致性。 例如,为信用卡交易保留资金基本上是悲观锁定的一种形式。 我们将在本文后面的云环境中讨论此类技术的使用。
(有关此主题的更多讨论,请参见SYS-CON Media网站上的“ Web服务事务 ”。)
本地交易与分布式交易
本地事务仅涉及一个资源管理器。 但是,当事务需要两个或多个资源管理器时会发生什么? 当您必须管理两个数据库中的数据或根据数据库中的某些状态在消息队列中发送消息时,可能会发生这种情况。 在这种情况下,仅提交第一个资源管理器,然后再提交第二个资源管理器将不起作用。 如果第二个资源管理器由于某些约束违规而回滚,那么如果第一个资源管理器是已提交的事务的一部分,您将如何回滚?
通常的方法(已经非常成功地使用了一种方法)是使用事务管理器 ,它协调事务中涉及的资源管理器。 然后,事务管理器使用分布式事务协议(通常为两阶段提交 )来提交事务。
在两阶段提交中,事务管理器首先要求所有参与的资源管理器保证事务在提交后将成功。 这是投票阶段 。 如果所有资源管理器都同意,那么将在提交阶段将事务提交给所有资源管理器。 如果甚至有一个资源管理器都拒绝提交,则所有资源管理器都将回滚并保证一致性。 图3显示了一个两阶段的提交事务。
图3.具有两阶段提交协议的分布式事务
此模型已成功用于基于主机的事务处理,Enterprise Java(JEE)应用程序服务器,Microsoft Transaction Server和其他系统中。 (请参阅“ Enterprise JavaBeans(EJB)和Microsoft Transaction Server(MTS)模型的详细比较 ”。)
请注意,分布式事务不限于应用程序服务器,还可以用于Web服务。 有一个针对Web服务的WS-Transaction标准,但我尚未实际使用它。
现实世界中的分布式交易
事务的主要属性是它的原子性。 在实际的分布式事务中,这可能无法完全实现,因此一致性也可能被破坏。 考虑消息队列和数据库之间的两阶段提交事务。 将状态写入数据库,并将相关消息发送到队列。 考虑到原子性和一致性,可以期望一旦从队列接收到消息,数据库状态将与之保持一致。 这是强一致性模型,在经典事务中可以保证。
但是,由于从事务管理器发送到两个资源管理器的提交是一个接一个地发送的,因此可以在第二个资源的更改之前看到第一个资源的更改。 例如,作为第二资源的数据库可能需要更多时间来进行实际提交,并且可能已经接收到提交给第一资源管理器的消息。 因此,处理将失败,因为尚未看到数据库状态。
这种情况不会经常发生,但偶尔会发生,我个人经历过。 (请参阅“ WebLogic上的两阶段提交竞争条件 ”和“ 消息/数据库竞争条件” 。)因此,即使在传统的分布式事务中,也存在不一致的窗口,其中事务最终才是一致的。 参见图4。
图4.即使是两阶段提交,不一致窗口

此外,两阶段提交协议要求完全执行两个阶段才能释放任何阻塞的资源,例如数据库记录。 为了确保事务的完整性(例如,在事务管理器中断或重新启动的情况下),事务管理器本身会编写自己的事务日志,该日志在停止时会保留下来。 然后,当事务管理器启动并且未完成的事务完成时,将读取此日志。 因此,需要一个持久性事务日志(通常写入文件系统)来支持事务管理器中的两阶段提交事务。
两阶段提交事务仅需要针对提交操作进行多个远程调用。 由于分布式事务的感知开销,这些电话往往是可以避免的,即使是在传统的JEE设置。 但是,可以在需要时使用它们以确保资源管理器之间的一致性。
事务异步(消息)协议
分布式事务真正投入的一种特定情况是将面向消息的中间件与数据库事务耦合。 确保仅在数据库事务成功时才将消息从队列中取出是一项很好的功能,它可以减少应用程序中的错误处理工作。 确保仅在可以成功落实数据库事务时才发送消息,这还有助于在数据库和消息传递队列之间提供一致性。
在这种设置中,分布式事务仅限于“本地”数据库和消息传递服务器,并且不包括其他资源管理器。 然后,消息传递系统确保发送和接收应用程序服务器之间的事务属性。 这种方法最终是一致的,因为仅在提交资源中的更改提交之后才更改接收资源。
图5.消息传递基础结构可以提供事务性最终一致性保证
使用面向消息的中间件,您可以创建具有事务质量的事件驱动的体系结构,并且可以将许多错误处理委托给事务管理器。
结论
在第1部分中,我们探讨了事务基础知识和分布式事务。 由于它们的特性,事务不仅使使用单个资源,而且尤其是跨资源的错误处理变得容易。 我向您展示了两阶段提交分布式事务是如何工作的,即使只有很小的时间间隔,它们甚至也只是“最终一致”。 您还了解到,事务管理器中的持久事务日志是分布式事务的必要条件。
在许多云部署中(例如,CloudFoundry),没有持久性文件系统可用。 因此,JEE应用程序服务器运行时无法编写其自己的事务管理器事务日志,因为没有两阶段提交事务。 同样,在某些新的运行时环境中,例如JavaScript服务器,运行时甚至根本没有可用的事务管理器。 (请参阅“ Java微服务最佳实践 ”。)
第2部分将研究仍可提供某些交易保证的分布式交易的替代方法。 使用这些替代方法,即使在云应用程序中,也可以确保交易质量,并确保正确处理了网上商店中的订单。
翻译自: https://www.ibm.com/developerworks/cloud/library/cl-manage-cloud-transactions_1/index.html