用于数据库事务的幂等性的制作方法

文档序号:7991870阅读:699来源:国知局
用于数据库事务的幂等性的制作方法
【专利摘要】提供了一种用于管理从客户端发送至服务器以供执行的事务性命令集的方法、机器和计算机可读取介质。第一服务器向客户端报告识别事务性命令集的逻辑标识符。第一服务器交付用于指示已交付集合的命令集相关信息。第二服务器基于客户端已经收到的逻辑标识符从客户端接收识别所述集合的请求。第二服务器确定请求在相应的对话中是否识别出接收用于执行的最新集合以及集合中是否存在尚未交付的任何事务。如果还有任何事务尚未交付,那么第二服务器就通过阻止第一会话中发布的所识别集合的完成来强行设定所识别集合的未交付状态。所识别集合可以随后无重复风险地在第二会话中执行。
【专利说明】用于数据库事务的幂等性
[0001]相关申请的交叉引用
[0002]本申请涉及并要求2011年9月9日提交的申请号为13/229,641且发明名称为“Recovering Stateful Read-Only Database Sessions”的美国申请的优先权,因此通过引用并入其全部内容,就像在本文中完整阐述过一样。所以 申请人:拒绝放弃专利申请或其审查历史中主张的任何权利要求范围。
[0003]本申请涉及并在2012年4月16日提交的申请号为13/448,267且发明名称也是“用于数据库事务的幂等性(Idempotence For Database Transactions) ”的美国专利申请,通过引用并入其全部内容,就像在本文中完整阐述过一样。
[0004]本申请还涉及:(I) 2004年8月12日提交的发明名称为“Transparent MigrationOf Stateless Sessions Across Servers” 的美国专利 US7747754,通过引用并入其全部内容,就像在本文中完整阐述过一样;(2) 2006年5月I日提交的发明名称为“DatabaseShutdown With Session Migration”的美国专利US7502824,通过引用并入其全部内容,就像在本文中完整阐述过一样;(3)2004年8月12日提交的发明名称为“TransparentSession Migration Across Servers”的美国专利US7552218,通过引用并入其全部内容,就像在本文中完整阐述过一样;(4) 2005年5月17日提交的发明名称为“Capturing AndRe-Creating The State Of A Queue When Migrating A Session”的美国专利US7415470,通过引用并入其全部内容,就像在本文中完整阐述过一样;(5)2007年4月4日提交的发明名称为“Migrating Temporary Data Of A Session” 的美国专利 US7634512,通过引用并入其全部内容,就像在本文中完整阐述过一样;(6)2011年3月30日提交的申请号为13/076,313 且发明名称为 “Application Workload Capture And Replay System” 的美国专利申请,通过引用并入其全部内容,就像在本文中完整阐述过一样。
【技术领域】
[0005]【技术领域】涉及管理从客户端发送至服务器以供执行的事务性命令集。
【背景技术】
[0006]服务器和客户端
[0007]服务器是一种为一个或多个客户端提供服务的操作软件过程。服务器可以是操作用于为客户端提供服务的相关软件的若干不同服务器实例构成的服务器实例(serverinstance)。客户端通过服务器连接跟服务器通信。具体地,客户端向服务器发送命令,而服务器执行命令并可选地向客户端送回结果。如本文中所用的服务器“操作”是指由服务器采用以执行一条或多条客户端命令的函数、过程或其他动作。单条命令可以触发多项服务器操作或者也可以对应于单项服务器操作。例如,某些命令可以请求服务器除了执行数据操作函数以外还要返回结果。另一些命令可以仅请求确认数据操作命令得到执行或者也可以不请求任何响应。
[0008]客户端可以要求执行在请求中明确的命令集。作为响应,服务器可以执行命令集并向客户端确认命令集已执行。例如,服务器可以向客户端提供结果或者可以仅提供命令集已执行的指示。服务器和客户端之间的连接可以随时地、按计划或不按计划地变为不可用。例如,服务器可能出错,或者支持服务器和客户端之间连接的网络设备或其他源也可能出错。如果服务器和客户端之间的连接在服务器响应命令集之前就已变为不可用,那么客户端就无法确定是否已经完成了命令集。
[0009]数据库服务器和数据库应用程序在本文中被提供分别作为服务器和客户端的示例。但是,本文介绍的各种技术可以应用于任何服务器-客户端系统。
[0010]数据库实例
[0011]数据库包括存储在一种或多种存储设备例如硬盘、随机存取记忆棒、存储集群或云存储系统内的数据和元数据。这样的数据和元数据可以根据例如关系和/或对象-关系数据库结构而按逻辑存储在数据库内。数据库应用程序通过向数据库实例提交命令促使数据库实例对存储在数据库内的数据执行操作而跟数据库服务器的实例(“数据库实例”)交互。数据库命令是用于访问或修改数据库中数据的请求。命令可以促使数据库实例对数据库内的数据执行操作和/或从数据库中返回数据。
[0012]在多节点数据库系统中,数据库可以通过多个数据库实例提供服务,并且每一个数据库实例都可以被设置用于访问全部或部分的数据库。服务器实例是集成的软件组件例如在一种或多种计算设备上运行的进程以及分配的用于在处理器上运行集成软件组件的计算资源例如内存、存储器或处理器周期的组合。数据库实例是集成的软件组件以及分配的用于访问、修改或以其他方式使用数据库的计算资源的组合。数据库实例可以分组为调用逻辑域的服务。多个数据库实例可以被安装或配置在单台机器或分离的多台机器上。在处理数据库命令时,数据库实例可以访问数据库或数据库中的信息缓存。在一个示例中,数据库被存储在非易失性存储器内,并且缓存被存储在易失性存储器内。
[0013]在多个数据库会话共享对相同数据的访问时,会话中执行的用户命令可以在一部分数据库被服务于该会话的数据库实例使用时锁定这部分数据库。例如,用户会话可以锁定用于排他性的读和/或写访问的部分,并且在所述部分已锁定时其他的用户会话被禁止访问和/或修改所述部分。用户会话在数据库实例完成对所述数据库部分的访问和/或修改之后再释放锁定。在锁定被释放后,其他的实例即可访问和/或修改所述部分或者获得对所述部分的锁定。
[0014]数据库命令可以用跟数据库实例所支持的数据库语言相符的数据库语句的形式提交给数据库实例。被多种数据库实例支持的数据库语言的一个非限制性示例是调用数据操作语言(“dml”)的结构化查询语言(“sql”),包括例如像Oracle?这样的数据
库服务器(譬如Oracle⑩Databasellg)所支持的专用形式的SQL。SQL数据定义语言
(“DDL”)指令被发送给数据库服务器以创建或配置数据库对象例如表、视图或复杂类型。尽管SQL作为一个示例而被提及,但是还有很多其他的示例性数据库语言和用于数据库的开放接口,其中任何一种都可以结合本文所述的技术使用。
[0015]过程化语言/结构化查询语言(“PL/SQL”)通过提供在过程化语言中获得的结构来扩展SQL,由此得到比标准SQL更加强大的结构化语言。PL/SQL命令被组织为由变量声明、包括过程和SQL命令的子命令以及异常处理命令构成的模块。PL/SQL命令可以被发送至数据库服务器以在执行PL/SQL命令时促使数据库服务器执行各种动作。数据库服务器还可以接收和执行基于Java的命令、远程过程调用命令或者跟其他编程语言或结构相符的命令。
[0016]可以在单次请求中将多条数据库命令从数据库客户端发送至数据库实例以完成工作。数据库命令可以由数据库实例处理,并且数据库实例可以针对请求中提交的所有命令用单次响应向数据库客户端返回结果。在单次交互的请求和响应中处理多条命令可以导致对数据库连接的高效使用。换句话说,在允许通过使用数据库连接的请求提交多条命令时,客户端通常使用数据库连接来提交请求的频率就比较低。
[0017]应用程序和逻辑连接
[0018]服务器例如中间层服务器(mid-tier server)为从数据库请求信息的应用程序提供数据库实例连接。中间层服务器是提供对一个或多个数据库服务器的访问、向一个或多个数据库服务器分配工作或者管理连往一个或多个数据库服务器的连接的服务器。应用程序是在一种或多种计算设备上运行的利用数据库连接从数据库中检索信息的任意逻辑。检索的信息可以展示或显示给应用程序的用户。例如,应用程序可以通过浏览器访问,其中应用程序从用户处接收输入并且向用户展示信息。应用程序可以是由用户在网络上通过门户网站访问的应用程序、安装在用户机器上的应用程序或者是分布在多台机器上的应用程序。
[0019]在一个示例中,Oracle? Fnslon⑩应用程序专门设置用于从Oracle?数据库中检索数据并且向Fusion⑩应用程序的用户显示信息。目前就有不同于Oracle⑧Vision⑩..应用程序的应用程序,并且在将来也可以开发出其他的数据库应用程序而并不背离本公开。
[0020]在一个示例中,应用程序针对数据库中的数据向中间层服务器发出请求。请求可以也可以不响应于用户输入而发送。中间层服务器从自由连接的连接池中选择连往数据库实例的自由连接。已被客户端或客户端群组选择和/或定制使用的数据库连接在本文中被称作“数据库会话”。数据库连接可以定制以满足作为用于特定客户端的数据库会话的特定需求,或者连接可以规范化以使得连接能够被用于支持各种客户端所用的各种数据库会话。中间层服务器通过选择的连接向数据库实例发送客户端请求,并且数据库实例访问数据库以处理请求。数据库服务器通过检索或修改数据库内的数据或者通过检索或修改数据库中的数据缓存内的数据来处理请求。在数据库服务器处理请求时,数据库服务器建立起用于数据库会话的状态。
[0021]中间层服务器经常存留连接池,其中包括连往数据库实例的连接。连接可以表示物理机构例如物理端口或逻辑接口或者两者兼有。可以存在逻辑连接(也就是数据库会话)到物理连接的一对一映射。另一方面,可以存在多于一个跟单个物理连接相关联的逻辑连接。在一个示例中,连接池内的自由连接仅包括尚未分配给用于处理请求的应用程序的那些连接。在工作完成后,连接即被送回连接池并且可供后续应用程序从池中借出。
[0022]在一个示例中,中间层服务器将逻辑连接分配给请求访问数据库的应用程序。逻辑连接被直接或间接地映射至多个物理连接中的一个。逻辑连接可以重新分配给新的物理连接而无需为应用程序重新分配新的逻辑连接。逻辑连接可以暴露给应用程序,并且应用程序可以在底层的物理连接改变时继续引用相同的逻辑连接。在一个示例中,特定的逻辑连接被表示为一个连接对象,该连接对象暴露给应用程序并且映射至另一个可以也可以不暴露给应用程序且可以是也可以不是另一个逻辑连接的连接对象。通过逻辑连接的层级将特定的逻辑连接映射至物理连接。
[0023]数据库会话不可用对应用程序的影响
[0024]在应用程序利用数据库会话来访问数据库时,应用程序建立起关于数据库会话的状态。例如,应用程序利用数据库会话来获取锁、创建临时变量或数据库对象、建立用户专用信息、建立应用程序专用信息、建立光标信息、建立数据的临时配置或选择和/或执行关于数据的其他部分完成操作以用于数据库会话中的后续处理。如果数据库会话在后续处理进行之前出错,那么锁、临时变量或数据库对象、用户专用信息、应用程序专用信息、光标信息、数据的临时配置或选择和/或部分完成的操作就变为对应用程序不可用,即使是应用程序试图在新的数据库会话中引用这些信息也不行。
[0025]在一个示例中,如果数据库会话所依赖的数据库实例出错或以其他方式变为不可用,那么数据库会话就可以出错或以其他方式变为不可用。在大多数情况下,数据库会话出错会导致应用程序由于进行中的数据库会话丢失而出错。应用程序的用户必须重启应用程序或应用程序的组件并且从登录开始,打开光标并检索数据,获取锁,创建临时变量或数据库对象,建立用户专用信息,建立应用程序专用信息,建立光标信息,建立数据的临时配置或选择和/或部分完成对数据的操作以用于数据库会话中的后续处理。在一个示例中,一旦数据库会话出错,用户可以得到死机的蓝屏或者被错误信息中断。
[0026]在现有的客户端-服务器系统中,如果在客户端和服务器之间有中断,那么客户端就会看到指示通信出错的错误信息。这种报错不会告知客户端提交是否执行了任何交付操作,或者过程调用是运行完成了所有预期交付的执行和会话状态的改变还是中途出错或者是更加糟糕地在从客户端断开后仍保持运行。
[0027]如果客户端想要获知向数据库的提交是否已交付,那么客户端应该加入自定义异常码以针对应用程序中每一个可能的交付点查询输出。考虑到系统在任何地方都有可能出错,由于必须专门针对每一次提交进行查询,因此这通常都不现实。在应用程序已建立并投入生产后,这是完全不切实际的。而且,因为事务可能会在执行查询之后立刻交付,所以查询并不能给出准确答案。实际上,在通信出错之后,服务器仍然可能运行提交而并未意识到客户端已断开。对于PL/SQL或Java操作或提交给数据库的其他过程,并没有关于过程的提交是已运行完成还是中途异常终止的记录。尽管可能已经交付,但是针对该过程的后续工作可能仍未完成。
[0028]无法识别出最终提交是已交付还是应该在随后的某一时刻交付还是并未运行完成能够由于用户和软件可能尝试重新提出已经存留的改变而导致重复的事务提交和其他形式的“逻辑讹误”。
[0029]现有技术并未提供在资源变为不可用时由所述资源执行的工作的相关信息。例如,应用程序在停机、有计划或无计划的情况下无法获知由所述资源处理的最后一次操作的输出。如果服务器在执行命令集时并且在服务器向客户端发送对命令集的响应之前宕机,那么客户端就无法获知在停机之前命令集是否已被服务器执行。即使是高度复杂的应用程序也可能会向终端用户暴露出停机问题。[0030]体验到资源停机的用户可能会很失望并且可能会由于错失业务机会、利用不良数据做出决策、故障检修的开销以及重启应用程序或重做工作损失的时间而损失收益。某些应用程序警告用户不得点击提交按钮两次,但是在用户未留意到不能这样做的警告时,如果两次提交都允许完成,那么就会建立重复的事务。
[0031]在另一个示例中,一旦数据库会话出错,在重载页面之前就禁止用户输入任何信息或者促使将任何命令提交给数据库。而且,不校验有哪些数据被存入数据库就重载页面可能会导致重复提交。应用程序可以禁止用户提交跟出错的数据库会话中丢失的状态有关或者如果所需信息不再可用就可能误操作的任何命令。在一个特定的示例中,已经展示给用户的域可以变灰以表示为了避免破坏数据库内存储的数据,这些域不能再通过应用程序修改。
[0032]即使数据库会话在用于第二数据库实例的过程中出错,第二数据库实例可能也无法获得在出错前交付给数据库的内容以外的任何关于数据库会话的信息。为了避免破坏数据库内的数据,应用程序可以将显示给用户的信息重设为跟已经交付给数据库的数据相匹配的信息。换句话说,在数据库实例出错时,用户可能会丢失恰好在出错前已经可为用户所用的临时信息。部分丢失的信息可以对应于被使用当前可用数据库会话的应用程序和/或用户显示、修改、选择或设置的信息或者将要通过现已不可用的数据库会话返回给应用程序和/或用户的信息。用户经常被迫再次重新输入各域的数据。
[0033]丢失已由用户输入、修改、选择和/或设置的信息可能会导致用户失望以及在应用程序或应用程序组件重启之后重新输入、重新修改、重新选择和/或重新设置信息上浪费时间。丢失的信息可以是由用户从其他来源例如视频、音频、邮件或文本消息中检索到的信息。在某些情况下,丢失的信息可能无法再进行检索。在发生故障且此时用户正接受支持服务提供商的帮助时,丢失信息的代价可能会特别高。丢失信息可能需要跟支持服务提供商进一步通信,或者甚至可能会导致用户丧失对应用程序、中间层服务器或数据库服务器或者提供应用程序、中间层服务器或数据库服务器的公司的可靠性的信心。此外,用户可以在出错之前选择、输入或修改对时间敏感的信息。要求用户在出错之后重新输入对时间敏感的信息可能会导致延时,从而造成业务、价值或用户对业务客户的信誉或用户的业务投资方面的损失。要求重新输入还可能会导致用户错失机会。例如,用户可能会遗漏用户先前已选择的事项或机会。
[0034]在本部分介绍的方法是能够推行的方法但不一定是先前已经设想或推行过的方法。因此,除非另有说明,否则不应认为在这本部分介绍的任何方法仅由于包含在本部分内就构成现有技术。
[0035]快速应用程序通知
[0036]应用程序开发商开发了处理服务器-客户端系统中的底层软件、硬件、底层通信层或其他资源的报告停机的应用程序。例如,对于OraclelOg,快速应用程序通知(“FAN”)在资源增加(也就是变为可用)或减少(也就是变为不可用)时向应用程序发送通知,并且应用程序开发商可以将其应用程序定制为响应于通知而改变应用程序的行为。
【专利附图】

【附图说明】
[0037]在附图中:[0038]图1示出了用于保存数据库系统内的事务状态的示例性步骤。
[0039]图2示出了用于管理数据库系统内的逻辑事务标识符(“LTXID”)的示例性步骤。
[0040]图3和图4示出了用于在事务开启并且执行数据定义语言(“DDL”)的语句时保存数据库系统内事务状态的示例性步骤。
[0041]图5示出了用于在数据库管理系统内执行事务性命令集的示例性步骤。
[0042]图6示出了用于在执行并行输入操作语言(“PDML”)的语句时管理数据库系统内事务状态的示例性步骤。
[0043]图7示出了可以在数据库系统内执行的示例性分布式事务。
[0044]图8示出了用于保存数据库系统内的事务状态的示例性方法的各个阶段。
[0045]图9示出了客户端利用数据库会话访问数据库的示例性结构。
[0046]图10示出了用于确定事务性命令集输出的示例性方法。
[0047]图11示出了用于强制执行命令集的示例性方法。
[0048]图12示出了用于检查客户端是否跟服务器同步的示例性方法。
[0049]图13示出了用于管理连接对象的示例性方法,所述连接对象包括会话识别信息以及用于在标识的会话内识别事务性命令集的信息。
[0050]图14示出了用于存留事务性命令集记录的示例性方法。
[0051]图15示出了可以被专门设置用于执行本文所述示例性方法的示例性计算机系统。
【具体实施方式】
[0052]在以下的说明内容中,为了便于解释,列举了很多具体的细节以提供对本发明的全面理解。但显而易见的是无需这些具体细节即可实现本发明。在其他的情况下,为了避免不必要地混淆本发明而以框图的形式示出了公知的结构和设备。
[0053]概述
[0054]本文公开了用于恢复数据库会话状态的技术。换句话说,所述技术能够被用于确定事务性命令集是否已完成或部分完成。例如,若一项或多项事务已经交付但是还有一项或多项另外的事务尚未交付,如果还要通过用于命令集的交付输出来返回更多的信息,或者如果还要由服务器以其他方式做更多的工作来完成命令集,那么命令集可为部分完成。尽管所述技术可以参照具体的实施例进行介绍,本文介绍的功能可以通过方法的实施、通过在执行时促使所述方法实施的一条或多条存储指令的集合或者通过专门设置用于实施所述方法的一台或多台机器的集合来提供。
[0055]在一个实施例中,会话中最新事务性命令集的相关信息可以被存储在响应于对会话的请求而发送至客户端的连接对象内。在一种示例性方法中,客户端在身份验证时、在校验时接收逻辑标识符例如逻辑事务ID(LTXID),并且在每一次交付时接收对该LTXID的更新。在示例中,每一次完成交付操作或者每一次完成包括至少一项交付操作的命令集都可以促使服务器实例为客户端提供新的或更新的LTXID。如果来自客户端的下一个命令集被交付,那么客户端就基于来自服务器的更新存留要在服务器处使用的下一个LTXID。服务器实例存储并控制变化的LTXID。在示例中,服务器实例将该信息存储或存留在会话所用的连接对象内。[0056]在一个实施例中,连接对象是JDBC连接对象或OCI服务句柄或ODP.Net连接对象。客户端应用程序从客户端库获取连接对象,并且客户端库利用连接对象打开连往服务器的物理连接(接口)。客户端库向服务器输送信息以使服务器能够验证客户端的身份并确定客户端的特权。直到连接对象被返回连接池之前,连接对象都保持分配给同一个应用程序。
[0057]第一服务器在第一会话中从客户端接收多个事务性命令集。如果通过一个命令集促使的任何事务被交付,那么用于该命令集的逻辑事务ID(LTXID)即被作为该交付操作的一部分存储。如果存在已经交付的事务和尚未交付的事务,那么存储的信息就指明命令集处于中间状态或嵌入状态。在一个实施例中,客户端在客户端和服务器之间的每一次交互期间都向服务器发送命令集以用于执行。在包括交付的任何命令集之后,用于该命令集的LTXID被更新以反映事务的完成,并且更新的LTXID被发送至客户端并存留在连接对象中。例如,LTXID可以与通过执行事务性命令集获得的任何结果一起发送至客户端。如果在事务性命令集中尚未交付任何事务,那么客户端就具有在当前事务性命令集之前由客户端发送用于执行的先前事务性命令集的LTXID。
[0058]在一个实施例中,任何交付都会导致LTXID的增加和返回新的LTXID。如果包含交付的命令集已经交付且完成,那么记录的LTXID (也就是先前的LTXID)就具有包括“已完成”命令集的状态或输出。在本实施例中,每一次交付都导致更新同一个会话的最新LTXID。在另一个实施例中,每一个完成的事务性命令集都导致更新同一个会话的最新LTXID。
[0059]第二服务器在第二会话中从客户端接收例如通过利用先前送至客户端的逻辑标识符来识别特定命令集的请求。第二服务器确定所述请求是否识别出接收用于在第一会话中执行的最新事务性命令集。如果答案为否,那么第二服务器可以将客户端尚未跟服务器同步的消息通知客户端。
[0060]第二服务器也可以确定在特定的命令集内是否尚未交付由特定命令集促使的事务,第二服务器通过阻止由该LTXID标识的事务免于交付来强行设定任何未交付状态从而保证输出。未交付状态包括如果第一会话已成功完成则本应在第一会话中交付但是因为第一会话并未完成而未能交付的任何状态。强行设定未交付状态避免了未交付状态在随后一旦另一个会话将未交付状态作为未交付处理后变为交付。一旦被阻止,第二服务器就可以通知客户端由该逻辑事务ID标识的命令集并未交付。一旦命令集已被阻止,第二服务器就可以通知客户端标识的事务并未交付(或者标识的事件并未发生)。第二服务器还可以促使执行第二会话中的特定命令集,由此在第一会话已被阻止之后促使事务或事件在第二会话中第一次发生。
[0061]第二服务器还要确定由特定命令集促使的至少一项事务是否已交付以及由特定命令集促使的任何其他事务是否尚未交付,或者是否可能仍未交付,或者在所述交付之后是否还有更多操作。在同一个实施例或各种其他的实施例中,第二服务器可以确定是否丢失了某种会话状态的改变和/或是否丢失了来自客户端的结果。如果事务已经交付但是在交付之后还有更多工作要做,那么服务器可以指示客户端所述交付是中间“嵌入”状态。客户端可以利用交付状态并且可以根据是否需要完成状态来选择继续与否。
[0062]在本文提供的各种示例中,数据库系统从数据库事务层的角度提供事务幂等性并且利用逻辑事务ID将对该信息的访问扩展至客户端。换句话说,数据库系统内的服务器记录由服务器利用逻辑事务ID交付的事务,并且服务器还通过利用逻辑事务ID阻止那些并未交付的事务来避免多于一次地完成事务。事务是改变数据的操作集合。在数据库系统中,操作通过一条或多条数据库命令来明确。交付事务是指对事务的改变在数据库内不变。为了保持数据的完整性,在交付事务时通过事务做出的改变以全做或不做的方式精确地(atomically)完成。要么交付所有的改变,要么就将事务退回重来。在永久性地完成事务时,逻辑事务标识符在交付时被记录为该事务的一部分。在交付后,将要使用的下一个逻辑事务标识符返回给客户端。在一个实施例中,构成逻辑事务ID—部分的运行交付编号在每一次交付完成后或者在包括至少一次交付的每一个命令集完成后被递增并返回给客户端作为LTXID的一部分。
[0063]在一个实施例中,如果第一数据库会话在处理事务时经历停机(outage),那么通过在第二会话中阻止由该LTXID标识的事务免于在第一会话交付而强行设定未交付状态,所述事务就可以在不同的第二数据库会话中完成而并没有仍要让会话在第一数据库会话中完成的风险。即使在一个会话中执行了多项事务,服务器也可以透明地并且以标定跟多个服务器的多个会话中的多个客户端的方式向客户端提供事务幂等性。
[0064]在一个实施例中,即使事务的执行在第一次尝试期间并未完成,服务器也允许交付事件。服务器在针对数据库交付事务时保存逻辑事务标识符(“LTXID”)。这些事务可以包括例如从内部PL/SQL、从内部服务器方的Java、从远程事务、从并行事务、从分布式事务以及从不能另外利用常规手段识别的标注中利用自动交付执行的事务。服务器利用LTXID支持最多一次的执行语义以使得无论是否存在多个进行中的事务副本,由LTXID保护的数据库事务都不能重复。换句话说,客户端可以提交若干次请求以完成同一项事务,并且服务器可以避免事务被完成多于一次。
[0065]在一个实施例中,服务器阻止进行中工作的交付以确保无论停机状况如何,通过例如浏览器或中间层客户端对同一项事务的再一次提交不能交付。服务器可以通过利用针对要重新提交该事务的每一次尝试的逻辑事务ID(LTXID)记录受完成事务的不同尝试影响的事务状态而识别完成同一项事务的重复尝试。例如,当服务器在命令集已被提交供执行的情况下尝试分解命令集时,服务器可以通过将代表事务性命令集的逻辑事务ID更新为阻止状态而强行设定未交付状态。
[0066]在一个实施例中,服务器记录针对跟LTXID相关联的命令集而交付的工作。服务器可以识别工作是作为顶层调用(客户端到服务器)的一部分而交付还是被嵌入在服务器处的过程例如PL/SQL或Java过程中还是构成涉及返回其他信息例如输出赋值或返回消息的交付操作的一部分。服务器可以存储命令集具有嵌入交付状态的指示。嵌入的交付状态标识在交付完成时执行交付的整个过程尚未运行完成。交付以外的任何工作直到父过程在数据库服务器返回并且所有结果都已由客户端接收之后才能确保完成。
[0067]在一个实施例中,如果客户端请求分解提交的事务,那么服务器就识别数据库系统是超前、同步还是落后于最初的提交。服务器可以在来自客户端的事务提交序列中有间隙时拒绝客户端的请求。如果客户端尝试强行完成事务,为此服务器或客户端在LTXID序列上不同步,那么服务器可以通知客户端同步错误。
[0068]在一个实施例中,客户端驱动器设有在LTXID通过从客户端到服务器的交付调用而递增时生效的回调。回调由更高层的应用程序例如Oracle的WebLogicServer和第三方应用程序使用以记录在客户端的当前LTXID。即使是客户端的数据库会话变为不可用,客户端也可以引用当前的LTXID。
[0069]在一个实施例中,LTXID被分配以确保命名空间在全局不同的数据库以及整合为可插入架构的数据库上的唯一性。
[0070]在一个实施例中,如果在该会话中来自客户端的任意调用集合成功交付了任何工作,服务器就递增交付序列。在用于调用的返回码返回到客户端时,将包括交付编号的逻辑事务ID跟客户端共享。交付序列被用于保持会话排序。以稳定的方式更新序列允许服务器验证客户端和服务器是否同步(也就是LTXID相同)。以稳定的方式更新序列还可以允许客户端确定下一个LTXID,不过如果LTXID处理是在服务器进行那就不需要这样做。如果LTXID处理是在服务器进行,客户端可以仅存留LTXID例如用于在先前的会话变为不可用时返回给新的会话。更新序列和序列状态的永久记录允许永久记录的成长跟会话数量而不是可能大得多的事务数量成比例。跟事务成比例的成长与跟会话成比例的更加有限的成长相比可能要使用更多的空间、内存和处理功率。
[0071]在一个实施例中,即使在停机前送回客户端的交付消息并未提供这样的信息,客户端通常也可以确定停机后最后一次交付操作的输出。服务器通过强行设定用于进行中和由于停机而退回重来的事务的未交付状态来确保将交付结果送回客户端。通过使该信息对客户端可用,服务器帮助客户端避免重复的事务提交以及如果用户和应用程序尝试重新发起已经交付数据库的改变而可能导致的其他形式的“逻辑谁误(logical Corruption) ”。
[0072]在一个实施例中,客户端不需要存留关联至特定数据库对象的修改编号。客户端可以通过查询逻辑标识符而不是受命令影响的对象来确定命令集是否已完成。例如,客户端可以利用LTXID查询命令集而不必考虑可能受事务性命令集影响的数据对象,从而就事务性命令集是否已经完成进行探查。
[0073]在一个实施例中,客户端无需为了确定过去提交的事务是否已交付以及这些交付是否已完成而提交另外的事务。例如,在每一次客户端提交可能会向数据库交付改变的其他命令时,客户端无需提交更新数据库中的事务历史表的DML命令。事务历史表可以在客户端提交事务性命令集时自动更新而无需客户端提交单独的语句来更新事务历史表。提交这些其他的语句将会造成服务器和客户端之间流量的明显增加。
[0074]在一个实施例中,服务器不允许客户端仅因为在客户端先前检查命令集的输出时事务性命令集尚未完成而重新提交事务性命令集。在重新执行命令集之前,服务器可以例如通过使用逻辑事务ID阻止事务历史表内的状态来尝试确定最后一项事务是否交付。如果先前会话中的另一个服务器已经更新了事务历史表来反映命令集已交付,那么第二服务器就指示客户端标识的事务已交付。换句话说,如果在更新事务历史表之前命令集已经在先前的会话中交付,那么在新会话中利用相同的LTXID重新执行的任何尝试都被交付状态阻止。但是,如果在测试事务历史表之前命令集并未在先前的会话中交付,那么先前会话中完成的事务即被阻止以使命令可以在新会话中无重复风险地重新执行。新会话中的重新执行要使用新的LTXID。如果其他的服务器在先前的会话中尝试交付事务性命令集,那么其他的服务器就会检测事务性命令集是否已被阻止以避免事务性命令集的重复执行(也就是不可预测的输出)。作为响应,其他的服务器会将已经在该会话中根据事务性命令集做出的任何改变退回重来。[0075]在一个实施例中,服务器保持单次往返行程的事务例如使用自动交付或嵌入在PL/SQL或Java中的那些事务的状态或输出。在从客户端到服务器的单次请求中可以打开和关闭一项或多项事务。例如,客户端可以调用PL/SQL过程或Java过程以在PL/SQL或Java模块内部的几个不同的交付点向数据库交付几项不同的事务。如果交付了任何事务,用于该LTXID的往返行程的输出即被交付。当交付被嵌入在模块内,交付的输出即被记录为嵌入。当交付是用于堆栈模块的最后一次操作时,交付可以被记录或更新为完整交付。
[0076]在不同的实施例中,服务器存留远程事务和/或自主事务和/或呼出事务的输出。
[0077]在一个实施例中,服务器存留用于PL/SQL、DDL和数据控制语言(“DCL”)命令的嵌入状态或输出。
[0078]在一个实施例中,服务器检测命令集何时包括事务。在事务开始时,服务器尝试记录LTXID作为事务的一部分。如果事务已开始或已交付或已被阻止,那么服务器就避免再次尝试该项事务。如果事务已开始或已交付,那么服务器就阻止完成随后的事务。如果当前的服务器在完成或阻止事务时成功阻止了其他尝试,那么服务器就可以尝试完成事务而无需承担事务完成多于一次的风险。
[0079]在另一个实施例中,服务器检测命令集何时包括事务。在事务开始时,服务器注册LTXID以记录在COMMIT作为事务的一部分。在COMMIT,如果事务已经例如在另一个会话中被阻止,那么当前的事务即被阻止而不得提交和退回重来。
[0080]在一个实施例中,即使数据库恢复为较早版本或者在随后的数据库实体中出现故障,服务器也可以处理来自客户端的事务序列。例如,服务器可以管理会话所用的LTXID以使交付序列单调增加,并且客户端可以依赖于这种稳定特性来确定已经发送的事务性命令集所用的但是尚未收到其结果的LTXID。
[0081]在一个实施例中,服务器可以高频地处理多项事务,并在处理时记录多项事务的输出。例如,服务器可以在交付事务性命令集时更新每一个LTXID的交付编号而无需针对每一项事务创建新的LTXID。
[0082]在一个实施例中,服务器屏蔽了数据库跟客户端或终端用户交流时涉及到的停机的冲击。因为服务器存留了交付输出,当一台服务器在执行事务的时候经历停机时,另一台服务器就能够获知事务的输出。服务器可以避免停机能够以其他方式造成对用户的可见冲击、造成输入数据丢失或者造成应用程序或应用程序组件的重启,避免消耗可观的时间和资源。服务器可以屏蔽停机和交流中断而无需给应用程序开发人员增加负担。服务器软件可以无重复风险地允许将请求在系统内的其他服务器重试或安全地继续。
[0083]获知事务输出可以得到改进的终端用户体验、更高的应用程序可用性、改进应用程序开发人员处理停机的生产力并在服务器、中间层和应用程序产品之间获得更好的集成和协作。服务器的功能无需显著改变应用程序即可实现。服务器的功能可以在服务会由于停机而意外中断的多种情况下避免中断用户服务。在一个示例中,服务器提供了在按计划和意外停机以及重复提交的情况下用于最多执行一次的语义的一般性架构。服务器可以存留交付输出,针对每一项事务提升已知的预期输出,并且支持最多一次的事务执行。
[0084]图9示出了客户端利用数据库会话访问数据库的示例性结构。在示例中,客户端902利用数据库会话904A访问数据库906。客户端902可以随后检测数据库会话904A的不可用性,并且不会丢失在客户端一方的会话中建立的无法传递至数据库会话904B的状态。例如,客户端902可以在会话904B重新运行最初在会话904A执行或请求执行的命令。
[0085]在一个实施例中,即使命令不可能交付,服务器也可以提供关于命令是否被交付的指示。例如,客户端可以请求命令集的输出,即使该命令集被部分或全部执行也不能完成事务。在通过阻止命令集强行设定输出后,服务器可以通过指明命令集并未完成事务来答复请求,和/或服务器可以指明无论命令集是否完成该命令集都不可能完成事务。服务器还可以向客户端指明在服务器一方关于命令集的进程,其中明确了哪些命令已执行或尚未执行。
[0086]在一个实施例中,本应响应于命令集从服务器发送至客户端的结果如果确实被发送则应包括客户端能够依赖于客户端一方操作的数值。如果客户端针对尚未返回这种数值的命令请求输出,那么即使在命令集中没有尚未完成的事务,客户端也可以接收到命令尚未完成的指示。在接收到对命令输出的请求之后,服务器可以确定结果本应包括这样的数值并且向客户端指明命令集尚未完成,直到由客户端接收到该数值为止。在执行命令时本应由服务器返回并且依赖于客户端的数据可以有多种类型,包括事务跟踪信息,在执行命令时是否出现了任何错误(并且可能是错误列表),客户端明确请求(根据选择或输出赋值返回)的其他数据和/或自动返回的数据例如受命令影响的行号。其他类型的信息例如事务当前是否打开可能并不依赖于客户端,并且客户端可能无法接收到该信息的事实并不能阻止服务器向客户端指明命令集已经完成。其他类型的信息尽管并未返回客户端也仍然可以保存在数据库内以用于在新建立的会话中返回给客户端。为了向客户端指明命令集已经完成,也可能并不需要保存的信息。
[0087]在一个实施例中,服务器可以将尚未返回给客户端的结果返回。如果服务器在新建立的会话中返回客户端本应依赖的结果,那么即使是在先前的会话中并未范围结果,月艮务器也可以随后在新建立的会话中将命令集作为完成处理。
[0088]在一个实施例中,命令集可以包括对会话状态做出明确改变的命令。例如,命令可以改变应该用于会话的语言。如果客户端针对改变会话状态的命令请求输出,那么如果该会话状态未存留在数据库内则客户端就可以接收命令尚未完成的指示。在接收对输出的请求时,服务器可以确定命令集本应改变会话状态并且直到在新建立的会话中对会话状态实施了改变之前都向客户端指明命令集仍未完成。
[0089]在一个实施例中,服务器可以对会话状态实施尚未完成的改变。如果服务器在新建立的会话中实施本应在先前的会话中若完成了命令就应实现的改变,那么即使在先前的会话中并未实现改变服务器也可以在新建立的会话中将命令作为完成处理。
[0090]在一个实施例中,服务器可以跟踪本应通过在从客户端到服务器的单次请求中提交的命令促使的多项事务。例如,服务器可以将基于针对命令的执行计划或者基于服务器已知用于促使事务的命令而预测要执行的事务编号。用这种方式,即使单个命令集促使了多项事务也可以跟踪针对每一项独立事务的交付输出。在本实施例中,服务器可以在针对包括多项事务的请求逐项事务处理的基础上而不是在逐项请求处理的基础上向客户端提供事务输出。在一个特定的示例中,客户端可以针对请求来请求事务输出,然后服务器可以通过提供用于多项事务的多个事务输出来响应,如果请求被执行完成就能促使或者就应该促使所述的多项事务。服务器可以报告个别事务的完成而不是将全部事务作为整体来报告,并且服务器可以阻止个别未交付事务而不是将所有的未交付事务作为整体来阻止。通过由服务器阻止并报告未交付状态来强行设定未交付状态可以是对来自客户端的识别促使了多项事务的命令集的信息请求的响应,或者通过识别命令集内的特定事务来完成。
[0091]在一个实施例中,响应于来自客户端的关于通过LTXID识别出的事务的信息请求,服务器可以确定执行由LTXID标识的交易的过程已死、确保无法完成或者预测为无法完成。在一个示例中,服务器可以通过借助负责用于执行由该LTXID标识的交易的其他组件进行校验来完成该确定。在本实施例中,即使服务器尚未阻止事务,服务器也可以向客户端报告事务已确保无法完成。
[0092]执行事务性命令
[0093]一种示例性数据库管理系统(DBMS)例如ORACLE、例如很多其他的DMBMS通过包括ORACLE的OCI驱动程序和ORACLE的JDBC驱动程序在内的各种客户端驱动程序接口为应用程序编写人员提供了基于事务的编程模型。通过驱动程序,顶层的SQL和PL/SQL调用建立起会话中的事务状态和非事务状态。在示例性系统中,客户端驱动程序向关系数据库管理系统(RDBMS)发送 SELECT、PL/SQL、ALTER SESSION、DML 和 TRUNCATE 语句并且在事务结束时交付改变。交付可以在用于服务器的同一个往返行程内进行,或者也可以在单独的往返行程内进行。
[0094]图1更加详细地示出了示例性系统中的不同组件和层。系统支持状态构建和交付处理。参照图1的工作流步骤,在登录阶段112,客户端发出调用以跟数据库系统104-110相连接。在登录阶段112,客户端驱动程序102完成认证握手并且建立客户端一方的会话句柄。在步骤116建立跟数据库系统的连接。在无事务阶段118,客户端102在步骤120中向RDBMS SQL层106发送SQL和PL/SQL命令。在122阶段,RDBMS SQL层106分析、关联并执行命令120。RDBMSSQL层106编译每一条语句并向SQL引擎或PL/SQL引擎发送请求。在步骤124执行命令120建立起用于会话的非事务性状态。在步骤126,服务器向客户端返回结果集合、输出关联、DML返回结果和ORACLE消息。这些结果的一部分被存留在客户端驱动程序内并传输至应用程序。
[0095]在有数据库事务的阶段128,客户端102在步骤130向RDBMSSQL层106发送DML命令以及包含DML的PL/SQL命令。在132阶段,RDBMS SQL层106分析、关联并执行命令130。SQL层编译每一条语句并向PL/SQL引擎和DML驱动程序发送请求。在步骤134执行命令启动一项或多项事务并且在步骤136建立RDBMS事务层108处的会话状态和事务状态。DML操作结果或ORACLE出错信息在步骤138返回给客户端102。
[0096]在交付工作阶段140客户端102发送交付请求或者已经在步骤142设定包含对RDBMS SQL层106的请求的自动交付。在交付阶段144,RDBMS SQL层106编译语句并且在步骤146向事务层发送交付请求。在刷新重做(flush redo)阶段148, RDBMS事务层108在步骤150将改变记录刷新至磁盘。RDBMS事务层108在步骤152在交付后的触发程序中构建成功的交付,并且促使交付后的触发程序返回RDBMS SQL层。在步骤154,RDBMS SQL层106向客户端102返回COMMIT消息。
[0097]在一个实施例中,客户端在身份验证时、在校验时以及在每一次事务或事务性命令集成功交付时接收逻辑事务ID,此时要接收对事务性命令集的确认。在一个实施例中,例如在前台过程或数据库实例崩溃或网络故障或出现任何一种异常终止的情况时,客户端驱动程序和DBMS之间就存在停机。客户端接收出错信息并且服务器一方的事务性和非事务性状态丢失。如果针对DBMS的最后一次通信是交付请求142或者可能包含交付请求,那么使用现有系统的应用程序在应用程序发送交付请求之后就无法获得交付输出。交付可能已经完成或者也可能并未完成,这取决于停机出现在哪个位置。例如,因为操作可能是在查询之后立刻交付,所以应用程序可能不知道交付消息丢失与否,并且应用程序无法安全查询最后一次交付请求的输出并恢复丢失的交付消息。
[0098]如果客户端已经进入工作并且在停机之前将该工作提交至服务器,那么客户端处的状态在停机之后得以保持,可能具有输入数据、返回数据和缓存的变量。应用程序需要以此运行的非事务性会话状态在现有的系统中丢失。如果事务已经开始并且交付尚未发出,那么进行中的事务就退回重来并且需要重新提交。如果事务已经开始并且交付也已发出,那么送回客户端的交付信息在现有的系统中无法持久。使用现有系统的客户端变成无法获知事务是否交付。
[0099]在现有的系统中,送回客户端的交付信息无法持久。如果在客户端和服务器之间有中断,那么客户端就会看到指示通信出错的错误信息。这种报错不会告知应用程序提交是否执行了任何交付操作,或者过程调用是运行完成了所有预期交付的执行和会话状态的改变还是中途出错或者甚至是在从客户端断开后仍保持运行。
[0100]应用程序开发人员可以写入自定义代码以在停机之后重新连接,但是应用程序没有用于将停机之间建立起来的非事务性会话状态重新建立或者尝试测试服务器以确定提交的工作是否交付或需要重复的机制。任何代码模块都有可能出错,并且应用程序开发人员不能在每一个交付点都执行这种形式的错误处理以确定指定的事务是否交付以及要恢复哪些状态以继续。应用程序可以利用应用程序和服务器之间的附加带宽写入修改编号或存储其他的一致信息以备能够查询。使用这些附加带宽是不合需要的,并且存留修改编号在按年月日排序方面以及在有故常而重定向至不同的数据库时也不安全。在没有主关键字或修改编号时,应用程序无法为了改变-跟踪而进行查询并且查询自身的方法是有根本缺陷的,原因是查询的内容可能在查询之后立刻交付。另外,对于提交包含多次交付的工作的批次管理程序,如果工作并未存留若重新提交就重启的位置记录,那么工作的重新提交就是不可行的。
[0101]通过应用跟踪应用程序的数据而提交的查询无法披露事务是否已经完成,原因是事务可能在该查询执行之后立刻交付。实际上,在通信出错之后,服务器仍然可能运行提交而并未意识到客户端已断开。对于PL/SQL或Java命令,没有用于过程提交的关于提交是运行完成还是中途异常终止的记录。尽管过程中的命令可能已经交付,但是针对该过程的后续工作可能仍未完成。
[0102]应用程序也不能跟踪本地事务、远程事务、分布式事务、并行事务、重复事务和XA事务。即使应用程序在特定的情况下能够确定在特定故障之前要执行哪些命令,重建在应用程序生存期内建立起来的非事务性会话状态对于在运行时修改非事务性会话的应用程序来说也并不简单。
[0103]无法识别出最后一次提交是已经交付还是应该在随后的某一时刻交付还是并未运行完成能够由于用户和软件可能尝试重新发起已经存留的改变而导致重复的事务提交和其他形式的“逻辑讹误”。
[0104]如果丢失的会话被再次提交,那么只要系统允许,重新提交就能够保持原子性和一致性。但是,如果针对事务建立的非事务性状态不正确或者如果事务已经交付,那么事务就不能被准确地重新提交。在现有的系统中,服务器和客户端之间的读操作没有幂等性。在缺少幂等性的情况下,重新提交能够导致事务的应用多于一次。
[0105]检测数据库会话的不可用性或超时
[0106]作为一个示例,客户端可以在客户端从用于在会话中执行的最新命令集接收结果之前或之后检测数据库会话的不可用性或超时。在一个实施例中,在客户端发送用于在数据库会话中执行的命令集之后,客户端才接收到数据库会话已无效的通知。作为响应,无论命令集是否执行,客户端都可以尝试阻止命令集。客户端可以可选地尝试在新的数据库会话中重新运行命令集。如果客户端选择在新的数据库会话中重新运行命令集,那么提供新数据库会话的服务器即可避免事务重复。例如,服务器可以避免重新执行已经在初始对话中执行过的命令。服务器也可以在新会话中重新运行事务之前阻止事务的执行。
[0107]在一个实施例中,监测逻辑接收指示数据库会话以变为应用程序不可用的信息。例如,信息可以指示数据库实例已出错或就要出错,或者由数据库示例提供给应用程序的服务或其他资源已出错或就要出错。作为另一个示例,信息可以指示数据库实例已经无法在至少阈值时间量内做出响应(也就是说实例已超时)。数据库会话的不可用性可以缘于计划内或意外的停机。对于计划内停机,即使数据库会话可能仍然可用,由监测逻辑接收的信息也指示停机是计划内的。指示计划内的“宕机”或停机允许在会话出故障和恢复之前完成工作。实际上,在使用连接池时,如果所有工作已完成,因为应用程序请求已经完成,所以就不需要恢复会话。相反,如果使用指定会话,重新运行就将会话转移至另一个实例以允许计划内的停机。在一个实施例中,数据库实例可以实现为对一种服务不可用但是对另一种服务可用,目的是为了降低数据库系统内的实例负荷。监测逻辑可以从记录原始数据库会话可用性的任何代理程序或组件接收信息。监测逻辑可以通过关闭数据库会话(例如由不可用数据库实例服务的会话)、打开新的数据库会话(例如由新的数据库实例服务的会话)并且在新的数据库会话中促使重新运行先前在现已不可用的数据库会话中发送的命令而对信息做出响应。在以这种方式用于“分配”工作时,重新运行应该位于负荷较小的数据库实例。
[0108]在一个实施例中,监测逻辑每一次检查数据库会话是否可用,应用程序都提交用于在数据库会话中执行的命令。因此,检测数据库会话是否已变为不可用可以随着接收要在数据库会话中执行的命令而同步进行。如果接口关闭那这种技术就可供使用。如果节点或网络故障,那么直到保持有效的TCP/IP过期之后才能接收到错误。
[0109]在一个实施例中,用于监测的有效技术是跟命令异步地接收快速应用程序通知(“FAN”)事件。FAN事件无论会话是否可用都有助于消除报废代码的路径校验并消除等待有效TCP的需求。
[0110]FAN监测逻辑订制向订购者发布可用性信息的服务。例如,监测逻辑可以在快速应用程序通知(“FAN”)事件中接收更新信息。通过快速通知借此公布很多事件用于系统状态变化的改变,应用程序就能够快速恢复并且会话也能够快速地重新平衡。在跟服务相关联的资源经历输出改变例如终止或启动/重启时,通知事件被立刻公布以供该事件的各种订购者使用。例如,通知事件在数据库实例变为可用或不可用时或者在实例中的服务变为可用或不可用时发出。通知事件包含使订购者能够根据匹配会话签名来识别受输出改变影响的特定会话的信息并由此做出响应。这就允许在资源无效时快速地放弃会话并快速终止正在进行的处理,还允许在资源重启时快速地重新平衡工作。
[0111]通知事件针对用于服务以及支持服务的资源例如特定实例、实例、节点或数据库集群的输出改变而出现。在由一个或多个实例提供的服务开始时,发出可以用于启动依赖于该服务的应用程序的通知事件(UP)。在由一个或多个实例提供的服务终止时,还有在实例、节点或网络终止时,发出停止相关应用程序的通知事件(DOWN)。在管理集群软件因为服务已经超过其故障阈值而不能再管理服务时,发出中断重试服务的应用程序的通知事件(NOT_RESTARTING)。在一个实施例中,NOT_RESTARTING事件启动到灾难服务的切换。
[0112]在连接至集群之后,唯一性的签名(也就是定位器)被生成用于相关会话并记录在句柄上作为连接的一部分。在一个实施例中,签名包括服务标识符、节点标识符以及数据库唯一名称和实例标识符,其中的每一个都跟会话相关联。在数据库集群的背景下,通知事件包含使订购者能够识别受输出改变影响的特定会话的信息也就是受影响会话的签名。对于某些事件类型,用于识别受影响会话的信息包括跟输出改变相关联的服务和数据库的标识符。对于另一些事件类型,用于识别受影响会话的信息还包括跟输出改变相关联的实例和节点的标识符。受影响的会话是签名跟事件有效负载内包含的签名相匹配的会话。
[0113]在各种实例中,检测之后存在不同的能够开始重新运行的时间点。监测逻辑可以从FAN事件接收信息,清除无效会话,但是并不立刻启动重新运行。例如,在接收到在已知要成为不可用的会话中执行的命令后,驱动程序建立新会话,在其中重建针对先前不可用会话而存在的客户端状态。在另一个实施例中,驱动程序可以响应于检测到不可用性而启动重新运行。
[0114]在一个实例中,监测逻辑响应于接收到要在已经变为不可用的数据库会话中执行的命令而触发在可用的数据库会话中重新运行。在本实施例中,监测逻辑可以检测到数据库会话已变为不可用而无需恢复数据库会话。例如,在数据库会话已变为不可用之后,如果没有更多的命令在该数据库会话中执行,那么就没有必要重新运行。在一个实施例中,监测逻辑通过FAN或接收到的错误获知会话不可用。如果存在运行中的命令那就调用重新运行,或者如果没有运行中的命令,那就在应用程序发送下一条命令时调用重新运行。如果应用程序再也不发送命令,那么重新运行就不会发生。
[0115]在另一个实例中,重新运行逻辑在接收到要在不可用的数据库会话中执行命令之前就触发在可用的数据库会话中重新运行。用这种方式,数据库会话可以在应用程序对数据库会话提交任何其他的命令之前就得到恢复。在接收到要在数据库会话中执行的另一条命令后,监测逻辑应该已经促使重新运行开始或完成以恢复数据库会话。因此,新接收到的命令由于只需会话即可重新运行而能更加高效地运行。
[0116]存留逻辑事务标识符(“LTXID”)
[0117]逻辑事务ID是全局唯一的ID,从应用程序的角度唯一性地定义了数据库会话。逻辑事务ID被存储在OCI会话句柄以及用于瘦JDBC驱动程序的连接对象内。逻辑事务ID是幂等性语义的基础。
[0118]用户通过数据库服务连接。为了实现最多执行一次的语义而向服务定义中加入新属性。该属性被称作commitjutcome。如果针对服务设定了该属性那就要创建逻辑事务ID ;否则就要存留pre-12c特性。以下的说明介绍了用于创建和存留逻辑事务ID的示例性步骤。
[0119]应用程序通过对应的驱动程序连接至数据库。在驱动程序连接至数据库时就启动新的数据库会话。作为会话创建的一部分还创建了新的逻辑事务ID(LTXID)。逻辑事务ID仅创建并存储在内存中的用户会话结构内并随后返回给客户端驱动程序。逻辑事务ID尚未存储在事务历史表内。新的逻辑事务ID被返回给驱动程序并且用户能够查询会话句柄已获取逻辑事务ID的值。逻辑事务ID以交付编号O开始。如果仅仅读取,那么LTXID不会改变。这是例如有效数据保护和只读数据库的情况。
[0120]如果应用程序使用连接池,那么连接池已经在服务器端和客户端的会话中存留了逻辑事务ID (LTXID)。在从池中校验时,应用程序使用会话中经其校验过的LTXID。该LTXID在最后一次登记时将交付编号返回连接池。
[0121]在一种示例性方法中,服务器接收用于在会话中执行的命令集。服务器会话已经存留了在身份验证时传输给客户端或者客户端在校验时包含的LTXID。一条或多条命令的集合如果在会话中完成就会促使执行:启动事务的第一服务器操作和交付事务的第二服务器操作。在该实例中,服务器确定命令集中是否包括至少一条如果执行就会启动至少一项事务的命令。响应于确定命令集包括至少一条如果执行就会启动至少一项事务的命令,月艮务器更新用于LTXID的存储信息作为交付操作的一部分。在一个实例中,服务器执行的服务器操作包括交付改变以及向事务历史表中插入或更新存储信息已指示命令集中的至少一项事务已经利用该LTXID交付。在交付后,新的LTXID生成并且在用于交付信息的返程中返回给客户端。
[0122]在一个实施例中,服务器存储的事务历史表包括用于会话中接收到的多个事务性命令集中的每一个事务性命令集的表项。服务器可以通过向用于命令集的事务历史表中增加表项来更新存储的信息以指示事务已经在命令集中开始。
[0123]图14示出了用于存留事务性命令集记录的示例性方法。在步骤1402,服务器接收用于在会话中执行的命令集。例如,服务器可以接收命名由服务器执行的一条或多条命令的序列的请求。在步骤1404,服务器确定命令集中的命令如果执行那是否会启动至少一项事务。如果命令并未启动事务,那么服务器就在步骤1406确定命令集是否包括任何其他的命令。如果答案为是,那么服务器就针对第二条命令重新执行步骤1404。如果服务器从未收到启动事务的命令,那么在步骤1408服务器就完成命令集的执行而无需注册或更新命令集所用的事务性信息例如LTXID。在另一个实施例中,即使命令集中没有事务,服务器也存储对LTXID的临时更新,但是除非服务器检测到事务或者要执行的潜在事务,否则临时更新并不交付。
[0124]另一方面,如果服务器确定命令集中的下一条命令若执行就会启动事务,那么服务器就在步骤1410注册成若该事务交付就要记录LTXID。服务器继续执行命令集,直到在步骤1412交付了开启的事务为止。在交付时,如果LTXID是第一次被看到,那就插入该LTXID0否则就更新LTXID。在一个实施例中,服务器在每一次交付时利用更新的LTXID记录命令集内的每一项交付事务。在另一个实施例中,服务器仅记录命令集中是否存在至少一项交付的事务。在交付开启的事务后,服务器在步骤1414插入或更新LTXID以指示开启的事务已交付。在交付后,在步骤1416生成下一个要使用的LTXID并返回至客户端。
[0125]逻辑事务标识符(“LTXID”)唯一地定义了事务性命令集并且用于确定是否交付了最后一项事务并且如果确已交付那么交付是否已完成。逻辑事务标识符可以包括用于数据库和实例的特有域,目的是为了检测故障是针对相同还是不同的数据库。包含这种域的逻辑事务标识符被称作“全局唯一”。接下来要使用的逻辑事务标识符由服务器端存留在每一个服务器端的会话中。事务标识符还可以包括用于实例、会话、版本和/或服务的特有域。在一个实例中,逻辑事务标识符被传输至并存留或储存在Oracle?调用接口(“0CI”)会话句柄或ODBC或ODP.Net会话句柄或者来自瘦Java?数据库互连(“JDBC”)驱动程序的连接对象内。客户端存留服务器计划要使用的下一个逻辑事务ID的副本。
[0126]在一个实施例中,系统根据逻辑事务标识符阻避免事务的重复执行。重复执行可以在交付时进行检测。在本实施例中的每一个交付点,如果事务已经交付就会违反服务器内的约束条件校验。如果是这种情况,那就放弃交付并且将事务退回重来。如果不是这种情况,交付就继续进行。允许交付继续进行就阻止了利用相同的LTXID交付事务的后续尝试。LTXID可以在交付时存储或更新。在交付之后,服务器计划针对该会话使用的下一个LTXID的副本被返回给客户端。
[0127]在停机后,客户端能够连接至服务器。然后使用来自先前连接的LTXID就能测试最后一项事务的输出。如果该事务并未交付,那么服务器可以阻止该LTXID以禁止使用该LTXID的在重新运行之前激活的先前运行中事务交付。如果LTXID已经交付或者如果LTXID先前被阻止,那么阻止LTXID的尝试可能会失败。
[0128]在一个实施例中,用于会话的当前LTXID描述了要在会话中交付的下一项事务。当前的LTXID可以已某种可预测的方式例如通过递加先前的LTXID来根据先前的LTXID计算。在服务器向客户端发送跟先前LTXID相关联的事务已交付的通知时,服务器向客户端输送服务器计划使用的下一个LTXID。
[0129]在一个实施例中,LTXID包括:
[0130]?版本
[0131]?数据库标识符
[0132]包括用于统一数据库的可插入数据库标识符
[0133]?数据库实例标识符
[0134]?逻辑会话编号(⑶ID)
[0135].交付编号
[0136]?服务器标识符
[0137]在各种实施例中,LTXID可以被用于针对以下情况支持最多执行一次的语义:
[0138]本地事务
[0139]自主事务
[0140]交付成功(自动交付)
[0141]只读性事务
[0142]循环性事务
[0143]分布式和远程事务
[0144]并行DML
[0145]作业调度事务
[0146]XA 事务[0147]逻辑会话编号(GUID)在会话建立时自动分配。在一个实施例中,GUID是应用程序无法读取的不透明结构。在一个实施例中,GUID针对事务历史的有效期是唯一的。
[0148]在一个实施例中,为了可量测性,运行的交付编号在交付数据库事务时增加。对于事务管理程序例如WebLogic来说可以明确一种附加属性。该属性被用于WebLogic服务器或Tuxedo或其他事务管理程序自身的全局事务标识符(“GTRID”)并且通常能够用于描述XA事务。
[0149]在一个实施例中,逻辑事务ID消除了重复事务的可能性。利用逻辑事务ID消除重复事务的可能性被称作自动事务幂等性。逻辑事务ID在交付时存留并且在退回重来后重新使用。在正常运行期间,LTXID被自动存留在客户端和服务器处用于每一项数据库事务的会话中。在交付时,逻辑事务ID被存留作为交付事务的一部分。
[0150]在一个实施例中,为了支持最多一次的协议,RDBMS在同意用于重试的存留期内存留逻辑事务ID。默认存留期是24小时。客户可以选择将该时段扩展至一周或更长,或者根据需要缩短该时段。存留期越长,利用旧LTXID阻止旧会话以免重新运行的最多一次的校验就持续得越长。在调用多个RDBMS时,就像在使用Data Guard和Golden Gate的情况,逻辑事务ID被复制到调用的每一个数据库。
[0151]在一个示例中,为12c ORACLE JDBC(瘦且为0CI)和OCI客户端提供的getLTXIDAPI允许应用程序拥有检索该会话要使用的下一个逻辑事务ID的能力。GET_LTXID_OUTCOME PL/SQL程序包允许应用程序利用获取的逻辑事务ID确定动作的输出。GET_LTXID_0UTC0ME程序包可以包括阻止LTXID免于交付以使得例如在使用该LTXID的事务运行中时输出是已知的。GET_LTXID_0UTC0ME在尝试重新运行之前调用并且可供各种应用使用以包含在它们的应用程序中。如本文所用,GET_LTXID_0UTC0ME和F0RCE_0UTC0ME能够可互换地使用以供引用具有该功能的程序包。在一个实施例中,封装返回事务是否交付、事务是不是完整的用户调用以及LTXID是否被阻止。
[0152]在一个实施例中,逻辑事务标识符到数据库事务的映射被存留在事务历史表内。对于指定的会话,在服务器执行会话中命令集内的COMMIT或最后一次COMMIT时,服务器可以插入若为第一次使用的LTXID或者更新当前的LTXID。插入或更新被存储在事务历史表内,在停机情况下可供其他的会话和服务器使用。
[0153]在一个实施例中,服务器在事务开启时执行回调以创建或更新LTXID。服务器在生成重做(redo)时插入第一次的取值,并且服务器以可预测的方式更新随后的取值。服务器在交付时也可以执行回调以创建或更新LTXID。在磁盘上的redo稳定之后,服务器可以将LTXID内的交付编号加一或者用某种其他的可预测或确定性的方式来更新交付编号。服务器可以在会话句柄上将交付编号的增量或其他更新跟交付输出一起返回。
[0154]在一个实施例中,用户连接至数据库并创建新的数据库会话。如果跟用户会话相关联的数据库服务具有“commitjutcome”属性设置,那就针对该会话创建新的逻辑事务ID(LTXID)。例如,RDBMS内核调用创建LTXID函数以将创建新的逻辑事务ID作为创建新的用户会话的一部分。逻辑事务ID此时仅存储在内存中而尚未存留。LTXID通过会话句柄返回给客户端。逻辑事务ID是唯一的,并且在同一集群或全局结构的数据库集合中的不同数据库实例上不能创建相同的逻辑事务ID。
[0155]在一个实施例中,LTXID仅针对处理SQL的用户会话创建。它们并不针对后台会话创建。它们并不针对由任务使用的从属过程例如内存监测程序(“MMON”)创建。在用于并行DML的实例中,只有并行协调程序具有相关联的LTXID。在用于作业调度程序的实例中,LTXID被管理用于在作业调度从属程序中运行的作业。
[0156]在一个实施例中,LTXID仅在使用支持LTXID的客户端时创建。支持LTXID的示例性客户端包括OC1、瘦JDBC和JDBC0C1、OCCI以及ODP.Net客户端。通过在会话所连接的服务上设置所谓的COMMIT_0UTC0ME来进行配置。
[0157]在一个实施例中,如果在验证用户时设备上设置了 commit_outcome属性,那就针对用户会话创建和管理LTXID。如果commit_outcome属性在连接之后设置,那么针对该会话就不在COMMIT处跟踪LTXID。如果commit_outcome被设定为FALSE,那么支持LTXID的现有会话就继续支持LTXID。
[0158]在一个实施例中,如果创建会话请求没有成功完成并且用户重试该操作,那就生成新的逻辑事务标识符。在本实施例中,旧的逻辑事务标识符不再重新使用。
[0159]在一个实施例中,LTXID上含有数据库的唯一名称和实例编号。利用LTXID接收事务输出请求的服务器可以识别原始数据库和实例,其中的事务利用作为LTXID —部分的数据库和实例标识符来提交。
[0160]图8示出了用于保存数据库系统内的事务状态的示例性方法的各个阶段。新的会话在步骤812开始。在该实例中,只要事务不发生任何改变,服务器就以典型的方式运行。当应用程序在步骤814发出创建首次redo的第一次改变之后,在步骤816注册两种交付回调:交付前回调和交付后回调。在事务交付时,交付前回调和交付后回调被自动调用。在步骤818,在事务于步骤820交付至磁盘之前调用交付前回调。在步骤822,在事务交付至磁盘之后调用交付后回调。
[0161]在一个实施例中,服务器在事务已交付且执行的COMMIT语句在PL/SQL或Java模块内嵌套或者是来自这些模块和函数的返回语句时将事务性命令集的输出设定为EMBEDDED (已嵌入),COMMIT语句在存储Java的过程中嵌套,或者COMMIT语句通过返回附加信息的调用来执行。返回处理行号的AUT0C0MMIT模式以及能够在包括事务中的SELECT在内的任何命令上设置的COMMIT ON SUCCESS就是应用程序在COMMIT之后预计最终在哪里获得更多信息的实例。服务器识别COMMIT是不是PL/SQL执行堆栈内的最后一项,并且在执行COMMIT时如果PL/SQL没有可返回的函数结果或输出参数就将用于LTXID的COMMIT输出设定为COMMITTED (已交付)而不是EMBEDDED。在一个实例中,如果COMMIT是PL/SQL执行堆栈内唯一的COMMIT,那么服务器就将COMMIT输出设定为COMMITTED而不是EMBEDDED。在另一个实例中,如果COMMIT先前在同一次PL/SQL执行中被设定为EMBEDDED并且最后一次的COMMIT执行和PL/SQL并未获得可返回的函数结果或输出参数,那么服务器就将COMMIT输出设定为COMMITTED。在另一个实例中,如果隐含的COMMIT是PL/SQL执行堆栈内的最后一项,那么服务器就将COMMIT输出设定为COMPLETED (已完成)而不是EMBEDDED。
[0162]在一个实例中,DDL命令作为依赖于DDL命令的递归和顶层的COMMIT组合而执行。COMMIT执行的编号和执行的层级都是DDL专用的。在实例中,如果DDL命令中出现任何交付,那么DDL命令就递加LTXID。用于LTXID的COMMIT输出在运行至完成时被更新为COMMITTED ο根据DDL命令执行的中间COMMIT具有的中间COMMIT输出为EMBEDDED。在一个特定的实例中,DDL命令将LTXID准确地递加一。换句话说,在该特定实例中,无论COMMIT的编号如何,具有递归COMMIT的命令集都超前LTXID恰好一步。在另一个实施例中,LTXID以某种其他的能够跟客户端共享的一致或可预测的方式改变。这就确保了 LTXID交付序列在到服务器的任何往返行程中都跟客户端同步。
[0163]下表示出了命令结构以及用于存留LTXID的对应过程的几个示例。
[0164]
【权利要求】
1.一种方法,包括: 在第二会话中由服务器从客户端接收请求,所述请求利用第一会话的逻辑标识符识别出由客户端在第一会话中发送的一条或多条命令的集合;其中所识别的一条或多条命令的集合如果在第一会话中已完成将促使实施: 交付事务的第一服务器操作; 由服务器确定事务尚未交付;并且 响应于所述请求并至少部分地基于确定事务尚未交付,服务器阻止第一会话中的事务完成。
2.如权利要求1所述的方法,进一步包括由服务器促使完成第二会话中的一条或多条命令的集合;其中事务在第一会话和第二会话两者中最多交付一次。
3.如权利要求1或2中的任意一项所述的方法,其中所述请求至少部分地基于在第一会话中完成先前的命令集之后被客户端接收到的逻辑标识符来识别所述一条或多条命令的集合。
4.如权利要求1至3中的任意一项所述的方法,其中所述服务器是托管第二会话的第二服务器,并且其中完成第一会话中的事务需要托管第一会话的第一服务器存留关于所识别的命令集的输出的存储信息。
5.如权利要求4所述的方法,其中阻止第一会话中的事务完成包括在第一会话以外存留关于所识别的命令集的输出的存储信息。
6.如权利要求5所述的方法,其中所述存储信息在事务交付时被存留在事务历史表内,并且其中事务历史表可供对数据库提供访问的包括所述服务器在内的多个服务器访问。
7.如权利要求1至6中的任意一项所述的方法,其中所述一条或多条命令的集合是从客户端到服务器的单用户调用,并且其中所述单用户调用如果在第一会话中完成将促使除了第一服务器操作以外的多项服务器操作的实施;其中所述多项服务器操作促使交付多项改变。
8.如权利要求1至7中的任意一项所述的方法,其中所述一条或多条命令的集合如果在所述会话中完成将在第一服务器操作和第二服务器操作之间促使至少一项服务器操作的实施以向客户端发送所识别的一条或多条命令的集合已交付的指示;其中所识别的一条或多条命令的集合已交付的指示直到第一服务器操作已交付事务并完成所述一条或多条命令的集合之后才发往客户端。
9.如权利要求8所述的方法,其中所述第一服务器操作如果在第一会话中完成就交付至少一项服务器操作对数据库内的一个或多个数据库对象实施的一项或多项临时改变。
10.如权利要求1至3或7至9中的任意一项所述的方法,其中所述服务器是在多个会话中对数据库提供访问的多个服务器中的第二服务器;其中多个会话中的每个会话每次最多被分配给一个服务器;其中由客户端在第二会话中发送一条或多条命令的集合之前,第一服务器在第一会话中向客户端提供对数据库的访问;其中客户端在第一会话中完成先前的命令集之后从第一服务 器接收逻辑标识符;其中由客户端在第一会话中发送一条或多条命令的集合之后第一会话变为对客户端不可用;并且其中所述请求至少部分地基于在第一会话中完成先前的命令集之后被客户端接收到的逻辑标识符来识别一条或多条命令的集合。
11.如权利要求1至2或4至10中的任意一项所述的方法,其中所述一条或多条命令的集合是一条或多条命令的第一集合,其中针对输出的请求至少部分地基于在第一会话中发送的多个命令集中的一条或多条命令的第一集合所特有的逻辑标识符来识别所述一条或多条命令的第一集合,其中标识符至少部分地基于在第一会话中发送的一条或多条命令的先前集合完成后才发送至客户端的指示,其中一条或多条命令的先前集合由客户端在第一会话中先于一条或多条命令的第一集合发送。
12.如权利要求1至2或4至10中的任意一项所述的方法,其中针对输出的请求至少部分地基于包括先前在第一会话中发送至客户端的信息的逻辑标识符来识别所述一条或多条命令的集合,其中所述逻辑标识符唯一地识别出: 在所述会话中发送的一条或多条命令的多个集合中的所述一条或多条命令的集合;以及 在多个服务器对数据库提供访问的多个会话中的所述会话,其中多个会话中的每个会话每次最多被分配给一个服务器。
13.如权利要求1至12中的任意一项所述的方法,进一步包括: 向客户端发送指示一条或多条命令的不同集合已交付的不同消息; 如果被交付就在送往客户端的不同消息中附带一条或多条命令的不同集合中的不同逻辑标识符,其中所述不同消息包括一条或多条命令的不同集合中不同的结果集合。
14.一种或多种存储指令的计算机可读取介质,所述指令在由一个或多个处理器执行时促使如权利要求1至13中的任意一项所述方法中的实施。
15.—种服务器,包括: 用于在第二会话中从客户端接收请求的装置,所述请求利用第一会话的逻辑标识符识别出由客户端在第一会话中发送的一条或多条命令的集合;其中所识别的一条或多条命令的集合如果在第一会话中已完成将促使实施: 交付事务的第一服务器操作; 用于确定事务尚未交付的装置;以及 用于响应于所述请求并至少部分地基于确定事务尚未交付而阻止第一会话中的事务完成的装置。
【文档编号】H04L29/08GK103782574SQ201280043616
【公开日】2014年5月7日 申请日期:2012年9月7日 优先权日:2011年9月9日
【发明者】C·L·科尔瑞恩, S·H·罗艾斯科, K·S·尼尔 申请人:甲骨文国际公司
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1