CN107070919A - 用于数据库事务的幂等性 - Google Patents
用于数据库事务的幂等性 Download PDFInfo
- Publication number
- CN107070919A CN107070919A CN201710250782.8A CN201710250782A CN107070919A CN 107070919 A CN107070919 A CN 107070919A CN 201710250782 A CN201710250782 A CN 201710250782A CN 107070919 A CN107070919 A CN 107070919A
- Authority
- CN
- China
- Prior art keywords
- affairs
- session
- ltxid
- server
- client
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Granted
Links
Classifications
-
- H—ELECTRICITY
- H04—ELECTRIC COMMUNICATION TECHNIQUE
- H04L—TRANSMISSION OF DIGITAL INFORMATION, e.g. TELEGRAPHIC COMMUNICATION
- H04L67/00—Network arrangements or protocols for supporting network services or applications
- H04L67/14—Session management
- H04L67/142—Managing session states for stateless protocols; Signalling session states; State transitions; Keeping-state mechanisms
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F16/00—Information retrieval; Database structures therefor; File system structures therefor
- G06F16/20—Information retrieval; Database structures therefor; File system structures therefor of structured data, e.g. relational data
- G06F16/21—Design, administration or maintenance of databases
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F16/00—Information retrieval; Database structures therefor; File system structures therefor
- G06F16/20—Information retrieval; Database structures therefor; File system structures therefor of structured data, e.g. relational data
- G06F16/23—Updating
- G06F16/2365—Ensuring data consistency and integrity
-
- H—ELECTRICITY
- H04—ELECTRIC COMMUNICATION TECHNIQUE
- H04L—TRANSMISSION OF DIGITAL INFORMATION, e.g. TELEGRAPHIC COMMUNICATION
- H04L67/00—Network arrangements or protocols for supporting network services or applications
- H04L67/01—Protocols
-
- H—ELECTRICITY
- H04—ELECTRIC COMMUNICATION TECHNIQUE
- H04L—TRANSMISSION OF DIGITAL INFORMATION, e.g. TELEGRAPHIC COMMUNICATION
- H04L67/00—Network arrangements or protocols for supporting network services or applications
- H04L67/14—Session management
- H04L67/146—Markers for unambiguous identification of a particular session, e.g. session cookie or URL-encoding
-
- H—ELECTRICITY
- H04—ELECTRIC COMMUNICATION TECHNIQUE
- H04L—TRANSMISSION OF DIGITAL INFORMATION, e.g. TELEGRAPHIC COMMUNICATION
- H04L67/00—Network arrangements or protocols for supporting network services or applications
- H04L67/14—Session management
- H04L67/148—Migration or transfer of sessions
Landscapes
- Engineering & Computer Science (AREA)
- Computer Networks & Wireless Communication (AREA)
- Signal Processing (AREA)
- Theoretical Computer Science (AREA)
- Databases & Information Systems (AREA)
- Data Mining & Analysis (AREA)
- Physics & Mathematics (AREA)
- General Engineering & Computer Science (AREA)
- General Physics & Mathematics (AREA)
- Computer Security & Cryptography (AREA)
- Information Retrieval, Db Structures And Fs Structures Therefor (AREA)
Abstract
本申请涉及用于数据库事务的幂等性。提供了一种用于管理从客户端发送至服务器以供执行的事务性命令集的方法、机器和计算机可读取介质。第一服务器向客户端报告识别事务性命令集的逻辑标识符。第一服务器交付用于指示已交付集合的命令集相关信息。第二服务器基于客户端已经收到的逻辑标识符从客户端接收识别所述集合的请求。第二服务器确定请求在相应的对话中是否识别出接收用于执行的最新集合以及集合中是否存在尚未交付的任何事务。如果还有任何事务尚未交付,那么第二服务器就通过阻止第一会话中发布的所识别集合的完成来强行设定所识别集合的未交付状态。所识别集合可以随后无重复风险地在第二会话中执行。
Description
本申请是申请日为2012年9月7日、申请号为201280043616.6、发明名称为“用于数据库事务的幂等性”的发明专利申请的分案申请。
技术领域
技术领域涉及管理从客户端发送至服务器以供执行的事务性命令集。
背景技术
服务器和客户端
服务器是一种为一个或多个客户端提供服务的操作软件过程。服务器可以是操作用于为客户端提供服务的相关软件的若干不同服务器实例构成的服务器实例(serverinstance)。客户端通过服务器连接跟服务器通信。具体地,客户端向服务器发送命令,而服务器执行命令并可选地向客户端送回结果。如本文中所用的服务器“操作”是指由服务器采用以执行一条或多条客户端命令的函数、过程或其他动作。单条命令可以触发多项服务器操作或者也可以对应于单项服务器操作。例如,某些命令可以请求服务器除了执行数据操作函数以外还要返回结果。另一些命令可以仅请求确认数据操作命令得到执行或者也可以不请求任何响应。
客户端可以要求执行在请求中明确的命令集。作为响应,服务器可以执行命令集并向客户端确认命令集已执行。例如,服务器可以向客户端提供结果或者可以仅提供命令集已执行的指示。服务器和客户端之间的连接可以随时地、按计划或不按计划地变为不可用。例如,服务器可能出错,或者支持服务器和客户端之间连接的网络设备或其他源也可能出错。如果服务器和客户端之间的连接在服务器响应命令集之前就已变为不可用,那么客户端就无法确定是否已经完成了命令集。
数据库服务器和数据库应用程序在本文中被提供分别作为服务器和客户端的示例。但是,本文介绍的各种技术可以应用于任何服务器-客户端系统。
数据库实例
数据库包括存储在一种或多种存储设备例如硬盘、随机存取记忆棒、存储集群或云存储系统内的数据和元数据。这样的数据和元数据可以根据例如关系和/或对象-关系数据库结构而按逻辑存储在数据库内。数据库应用程序通过向数据库实例提交命令促使数据库实例对存储在数据库内的数据执行操作而跟数据库服务器的实例(“数据库实例”)交互。数据库命令是用于访问或修改数据库中数据的请求。命令可以促使数据库实例对数据库内的数据执行操作和/或从数据库中返回数据。
在多节点数据库系统中,数据库可以通过多个数据库实例提供服务,并且每一个数据库实例都可以被设置用于访问全部或部分的数据库。服务器实例是集成的软件组件例如在一种或多种计算设备上运行的进程以及分配的用于在处理器上运行集成软件组件的计算资源例如内存、存储器或处理器周期的组合。数据库实例是集成的软件组件以及分配的用于访问、修改或以其他方式使用数据库的计算资源的组合。数据库实例可以分组为调用逻辑域的服务。多个数据库实例可以被安装或配置在单台机器或分离的多台机器上。在处理数据库命令时,数据库实例可以访问数据库或数据库中的信息缓存。在一个示例中,数据库被存储在非易失性存储器内,并且缓存被存储在易失性存储器内。
在多个数据库会话共享对相同数据的访问时,会话中执行的用户命令可以在一部分数据库被服务于该会话的数据库实例使用时锁定这部分数据库。例如,用户会话可以锁定用于排他性的读和/或写访问的部分,并且在所述部分已锁定时其他的用户会话被禁止访问和/或修改所述部分。用户会话在数据库实例完成对所述数据库部分的访问和/或修改之后再释放锁定。在锁定被释放后,其他的实例即可访问和/或修改所述部分或者获得对所述部分的锁定。
数据库命令可以用跟数据库实例所支持的数据库语言相符的数据库语句的形式提交给数据库实例。被多种数据库实例支持的数据库语言的一个非限制性示例是调用数据操作语言(“DML”)的结构化查询语言(“SQL”),包括例如像这样的数据库服务器(譬如Database 11g)所支持的专用形式的SQL。SQL数据定义语言(“DDL”)指令被发送给数据库服务器以创建或配置数据库对象例如表、视图或复杂类型。尽管SQL作为一个示例而被提及,但是还有很多其他的示例性数据库语言和用于数据库的开放接口,其中任何一种都可以结合本文所述的技术使用。
过程化语言/结构化查询语言(“PL/SQL”)通过提供在过程化语言中获得的结构来扩展SQL,由此得到比标准SQL更加强大的结构化语言。PL/SQL命令被组织为由变量声明、包括过程和SQL命令的子命令以及异常处理命令构成的模块。PL/SQL命令可以被发送至数据库服务器以在执行PL/SQL命令时促使数据库服务器执行各种动作。数据库服务器还可以接收和执行基于Java的命令、远程过程调用命令或者跟其他编程语言或结构相符的命令。
可以在单次请求中将多条数据库命令从数据库客户端发送至数据库实例以完成工作。数据库命令可以由数据库实例处理,并且数据库实例可以针对请求中提交的所有命令用单次响应向数据库客户端返回结果。在单次交互的请求和响应中处理多条命令可以导致对数据库连接的高效使用。换句话说,在允许通过使用数据库连接的请求提交多条命令时,客户端通常使用数据库连接来提交请求的频率就比较低。
应用程序和逻辑连接
服务器例如中间层服务器(mid-tier server)为从数据库请求信息的应用程序提供数据库实例连接。中间层服务器是提供对一个或多个数据库服务器的访问、向一个或多个数据库服务器分配工作或者管理连往一个或多个数据库服务器的连接的服务器。应用程序是在一种或多种计算设备上运行的利用数据库连接从数据库中检索信息的任意逻辑。检索的信息可以展示或显示给应用程序的用户。例如,应用程序可以通过浏览器访问,其中应用程序从用户处接收输入并且向用户展示信息。应用程序可以是由用户在网络上通过门户网站访问的应用程序、安装在用户机器上的应用程序或者是分布在多台机器上的应用程序。
在一个示例中,应用程序专门设置用于从数据库中检索数据并且向应用程序的用户显示信息。目前就有不同于应用程序的应用程序,并且在将来也可以开发出其他的数据库应用程序而并不背离本公开。
在一个示例中,应用程序针对数据库中的数据向中间层服务器发出请求。请求可以也可以不响应于用户输入而发送。中间层服务器从自由连接的连接池中选择连往数据库实例的自由连接。已被客户端或客户端群组选择和/或定制使用的数据库连接在本文中被称作“数据库会话”。数据库连接可以定制以满足作为用于特定客户端的数据库会话的特定需求,或者连接可以规范化以使得连接能够被用于支持各种客户端所用的各种数据库会话。中间层服务器通过选择的连接向数据库实例发送客户端请求,并且数据库实例访问数据库以处理请求。数据库服务器通过检索或修改数据库内的数据或者通过检索或修改数据库中的数据缓存内的数据来处理请求。在数据库服务器处理请求时,数据库服务器建立起用于数据库会话的状态。
中间层服务器经常存留连接池,其中包括连往数据库实例的连接。连接可以表示物理机构例如物理端口或逻辑接口或者两者兼有。可以存在逻辑连接(也就是数据库会话)到物理连接的一对一映射。另一方面,可以存在多于一个跟单个物理连接相关联的逻辑连接。在一个示例中,连接池内的自由连接仅包括尚未分配给用于处理请求的应用程序的那些连接。在工作完成后,连接即被送回连接池并且可供后续应用程序从池中借出。
在一个示例中,中间层服务器将逻辑连接分配给请求访问数据库的应用程序。逻辑连接被直接或间接地映射至多个物理连接中的一个。逻辑连接可以重新分配给新的物理连接而无需为应用程序重新分配新的逻辑连接。逻辑连接可以暴露给应用程序,并且应用程序可以在底层的物理连接改变时继续引用相同的逻辑连接。在一个示例中,特定的逻辑连接被表示为一个连接对象,该连接对象暴露给应用程序并且映射至另一个可以也可以不暴露给应用程序且可以是也可以不是另一个逻辑连接的连接对象。通过逻辑连接的层级将特定的逻辑连接映射至物理连接。
数据库会话不可用对应用程序的影响
在应用程序利用数据库会话来访问数据库时,应用程序建立起关于数据库会话的状态。例如,应用程序利用数据库会话来获取锁、创建临时变量或数据库对象、建立用户专用信息、建立应用程序专用信息、建立光标信息、建立数据的临时配置或选择和/或执行关于数据的其他部分完成操作以用于数据库会话中的后续处理。如果数据库会话在后续处理进行之前出错,那么锁、临时变量或数据库对象、用户专用信息、应用程序专用信息、光标信息、数据的临时配置或选择和/或部分完成的操作就变为对应用程序不可用,即使是应用程序试图在新的数据库会话中引用这些信息也不行。
在一个示例中,如果数据库会话所依赖的数据库实例出错或以其他方式变为不可用,那么数据库会话就可以出错或以其他方式变为不可用。在大多数情况下,数据库会话出错会导致应用程序由于进行中的数据库会话丢失而出错。应用程序的用户必须重启应用程序或应用程序的组件并且从登录开始,打开光标并检索数据,获取锁,创建临时变量或数据库对象,建立用户专用信息,建立应用程序专用信息,建立光标信息,建立数据的临时配置或选择和/或部分完成对数据的操作以用于数据库会话中的后续处理。在一个示例中,一旦数据库会话出错,用户可以得到死机的蓝屏或者被错误信息中断。
在现有的客户端-服务器系统中,如果在客户端和服务器之间有中断,那么客户端就会看到指示通信出错的错误信息。这种报错不会告知客户端提交是否执行了任何交付操作,或者过程调用是运行完成了所有预期交付的执行和会话状态的改变还是中途出错或者是更加糟糕地在从客户端断开后仍保持运行。
如果客户端想要获知向数据库的提交是否已交付,那么客户端应该加入自定义异常码以针对应用程序中每一个可能的交付点查询输出。考虑到系统在任何地方都有可能出错,由于必须专门针对每一次提交进行查询,因此这通常都不现实。在应用程序已建立并投入生产后,这是完全不切实际的。而且,因为事务可能会在执行查询之后立刻交付,所以查询并不能给出准确答案。实际上,在通信出错之后,服务器仍然可能运行提交而并未意识到客户端已断开。对于PL/SQL或Java操作或提交给数据库的其他过程,并没有关于过程的提交是已运行完成还是中途异常终止的记录。尽管可能已经交付,但是针对该过程的后续工作可能仍未完成。
无法识别出最终提交是已交付还是应该在随后的某一时刻交付还是并未运行完成能够由于用户和软件可能尝试重新提出已经存留的改变而导致重复的事务提交和其他形式的“逻辑讹误”。
现有技术并未提供在资源变为不可用时由所述资源执行的工作的相关信息。例如,应用程序在停机、有计划或无计划的情况下无法获知由所述资源处理的最后一次操作的输出。如果服务器在执行命令集时并且在服务器向客户端发送对命令集的响应之前宕机,那么客户端就无法获知在停机之前命令集是否已被服务器执行。即使是高度复杂的应用程序也可能会向终端用户暴露出停机问题。
体验到资源停机的用户可能会很失望并且可能会由于错失业务机会、利用不良数据做出决策、故障检修的开销以及重启应用程序或重做工作损失的时间而损失收益。某些应用程序警告用户不得点击提交按钮两次,但是在用户未留意到不能这样做的警告时,如果两次提交都允许完成,那么就会建立重复的事务。
在另一个示例中,一旦数据库会话出错,在重载页面之前就禁止用户输入任何信息或者促使将任何命令提交给数据库。而且,不校验有哪些数据被存入数据库就重载页面可能会导致重复提交。应用程序可以禁止用户提交跟出错的数据库会话中丢失的状态有关或者如果所需信息不再可用就可能误操作的任何命令。在一个特定的示例中,已经展示给用户的域可以变灰以表示为了避免破坏数据库内存储的数据,这些域不能再通过应用程序修改。
即使数据库会话在用于第二数据库实例的过程中出错,第二数据库实例可能也无法获得在出错前交付给数据库的内容以外的任何关于数据库会话的信息。为了避免破坏数据库内的数据,应用程序可以将显示给用户的信息重设为跟已经交付给数据库的数据相匹配的信息。换句话说,在数据库实例出错时,用户可能会丢失恰好在出错前已经可为用户所用的临时信息。部分丢失的信息可以对应于被使用当前可用数据库会话的应用程序和/或用户显示、修改、选择或设置的信息或者将要通过现已不可用的数据库会话返回给应用程序和/或用户的信息。用户经常被迫再次重新输入各域的数据。
丢失已由用户输入、修改、选择和/或设置的信息可能会导致用户失望以及在应用程序或应用程序组件重启之后重新输入、重新修改、重新选择和/或重新设置信息上浪费时间。丢失的信息可以是由用户从其他来源例如视频、音频、邮件或文本消息中检索到的信息。在某些情况下,丢失的信息可能无法再进行检索。在发生故障且此时用户正接受支持服务提供商的帮助时,丢失信息的代价可能会特别高。丢失信息可能需要跟支持服务提供商进一步通信,或者甚至可能会导致用户丧失对应用程序、中间层服务器或数据库服务器或者提供应用程序、中间层服务器或数据库服务器的公司的可靠性的信心。此外,用户可以在出错之前选择、输入或修改对时间敏感的信息。要求用户在出错之后重新输入对时间敏感的信息可能会导致延时,从而造成业务、价值或用户对业务客户的信誉或用户的业务投资方面的损失。要求重新输入还可能会导致用户错失机会。例如,用户可能会遗漏用户先前已选择的事项或机会。
在本部分介绍的方法是能够推行的方法但不一定是先前已经设想或推行过的方法。因此,除非另有说明,否则不应认为在这本部分介绍的任何方法仅由于包含在本部分内就构成现有技术。
快速应用程序通知
应用程序开发商开发了处理服务器-客户端系统中的底层软件、硬件、底层通信层或其他资源的报告停机的应用程序。例如,对于Oracle 10g,快速应用程序通知(“FAN”)在资源增加(也就是变为可用)或减少(也就是变为不可用)时向应用程序发送通知,并且应用程序开发商可以将其应用程序定制为响应于通知而改变应用程序的行为。
附图说明
在附图中:
图1示出了用于保存数据库系统内的事务状态的示例性步骤。
图2示出了用于管理数据库系统内的逻辑事务标识符(“LTXID”)的示例性步骤。
图3和图4示出了用于在事务开启并且执行数据定义语言(“DDL”)的语句时保存数据库系统内事务状态的示例性步骤。
图5示出了用于在数据库管理系统内执行事务性命令集的示例性步骤。
图6示出了用于在执行并行输入操作语言(“PDML”)的语句时管理数据库系统内事务状态的示例性步骤。
图7示出了可以在数据库系统内执行的示例性分布式事务。
图8示出了用于保存数据库系统内的事务状态的示例性方法的各个阶段。
图9示出了客户端利用数据库会话访问数据库的示例性结构。
图10示出了用于确定事务性命令集输出的示例性方法。
图11示出了用于强制执行命令集的示例性方法。
图12示出了用于检查客户端是否跟服务器同步的示例性方法。
图13示出了用于管理连接对象的示例性方法,所述连接对象包括会话识别信息以及用于在标识的会话内识别事务性命令集的信息。
图14示出了用于存留事务性命令集记录的示例性方法。
图15示出了可以被专门设置用于执行本文所述示例性方法的示例性计算机系统。
具体实施方式
在以下的说明内容中,为了便于解释,列举了很多具体的细节以提供对本发明的全面理解。但显而易见的是无需这些具体细节即可实现本发明。在其他的情况下,为了避免不必要地混淆本发明而以框图的形式示出了公知的结构和设备。
概述
本文公开了用于恢复数据库会话状态的技术。换句话说,所述技术能够被用于确定事务性命令集是否已完成或部分完成。例如,若一项或多项事务已经交付但是还有一项或多项另外的事务尚未交付,如果还要通过用于命令集的交付输出来返回更多的信息,或者如果还要由服务器以其他方式做更多的工作来完成命令集,那么命令集可为部分完成。尽管所述技术可以参照具体的实施例进行介绍,本文介绍的功能可以通过方法的实施、通过在执行时促使所述方法实施的一条或多条存储指令的集合或者通过专门设置用于实施所述方法的一台或多台机器的集合来提供。
在一个实施例中,会话中最新事务性命令集的相关信息可以被存储在响应于对会话的请求而发送至客户端的连接对象内。在一种示例性方法中,客户端在身份验证时、在校验时接收逻辑标识符例如逻辑事务ID(LTXID),并且在每一次交付时接收对该LTXID的更新。在示例中,每一次完成交付操作或者每一次完成包括至少一项交付操作的命令集都可以促使服务器实例为客户端提供新的或更新的LTXID。如果来自客户端的下一个命令集被交付,那么客户端就基于来自服务器的更新存留要在服务器处使用的下一个LTXID。服务器实例存储并控制变化的LTXID。在示例中,服务器实例将该信息存储或存留在会话所用的连接对象内。
在一个实施例中,连接对象是JDBC连接对象或OCI服务句柄或ODP.Net连接对象。客户端应用程序从客户端库获取连接对象,并且客户端库利用连接对象打开连往服务器的物理连接(接口)。客户端库向服务器输送信息以使服务器能够验证客户端的身份并确定客户端的特权。直到连接对象被返回连接池之前,连接对象都保持分配给同一个应用程序。
第一服务器在第一会话中从客户端接收多个事务性命令集。如果通过一个命令集促使的任何事务被交付,那么用于该命令集的逻辑事务ID(LTXID)即被作为该交付操作的一部分存储。如果存在已经交付的事务和尚未交付的事务,那么存储的信息就指明命令集处于中间状态或嵌入状态。在一个实施例中,客户端在客户端和服务器之间的每一次交互期间都向服务器发送命令集以用于执行。在包括交付的任何命令集之后,用于该命令集的LTXID被更新以反映事务的完成,并且更新的LTXID被发送至客户端并存留在连接对象中。例如,LTXID可以与通过执行事务性命令集获得的任何结果一起发送至客户端。如果在事务性命令集中尚未交付任何事务,那么客户端就具有在当前事务性命令集之前由客户端发送用于执行的先前事务性命令集的LTXID。
在一个实施例中,任何交付都会导致LTXID的增加和返回新的LTXID。如果包含交付的命令集已经交付且完成,那么记录的LTXID(也就是先前的LTXID)就具有包括“已完成”命令集的状态或输出。在本实施例中,每一次交付都导致更新同一个会话的最新LTXID。在另一个实施例中,每一个完成的事务性命令集都导致更新同一个会话的最新LTXID。
第二服务器在第二会话中从客户端接收例如通过利用先前送至客户端的逻辑标识符来识别特定命令集的请求。第二服务器确定所述请求是否识别出接收用于在第一会话中执行的最新事务性命令集。如果答案为否,那么第二服务器可以将客户端尚未跟服务器同步的消息通知客户端。
第二服务器也可以确定在特定的命令集内是否尚未交付由特定命令集促使的事务,第二服务器通过阻止由该LTXID标识的事务免于交付来强行设定任何未交付状态从而保证输出。未交付状态包括如果第一会话已成功完成则本应在第一会话中交付但是因为第一会话并未完成而未能交付的任何状态。强行设定未交付状态避免了未交付状态在随后一旦另一个会话将未交付状态作为未交付处理后变为交付。一旦被阻止,第二服务器就可以通知客户端由该逻辑事务ID标识的命令集并未交付。一旦命令集已被阻止,第二服务器就可以通知客户端标识的事务并未交付(或者标识的事件并未发生)。第二服务器还可以促使执行第二会话中的特定命令集,由此在第一会话已被阻止之后促使事务或事件在第二会话中第一次发生。
第二服务器还要确定由特定命令集促使的至少一项事务是否已交付以及由特定命令集促使的任何其他事务是否尚未交付,或者是否可能仍未交付,或者在所述交付之后是否还有更多操作。在同一个实施例或各种其他的实施例中,第二服务器可以确定是否丢失了某种会话状态的改变和/或是否丢失了来自客户端的结果。如果事务已经交付但是在交付之后还有更多工作要做,那么服务器可以指示客户端所述交付是中间“嵌入”状态。客户端可以利用交付状态并且可以根据是否需要完成状态来选择继续与否。
在本文提供的各种示例中,数据库系统从数据库事务层的角度提供事务幂等性并且利用逻辑事务ID将对该信息的访问扩展至客户端。换句话说,数据库系统内的服务器记录由服务器利用逻辑事务ID交付的事务,并且服务器还通过利用逻辑事务ID阻止那些并未交付的事务来避免多于一次地完成事务。事务是改变数据的操作集合。在数据库系统中,操作通过一条或多条数据库命令来明确。交付事务是指对事务的改变在数据库内不变。为了保持数据的完整性,在交付事务时通过事务做出的改变以全做或不做的方式精确地(atomically)完成。要么交付所有的改变,要么就将事务退回重来。在永久性地完成事务时,逻辑事务标识符在交付时被记录为该事务的一部分。在交付后,将要使用的下一个逻辑事务标识符返回给客户端。在一个实施例中,构成逻辑事务ID一部分的运行交付编号在每一次交付完成后或者在包括至少一次交付的每一个命令集完成后被递增并返回给客户端作为LTXID的一部分。
在一个实施例中,如果第一数据库会话在处理事务时经历停机(outage),那么通过在第二会话中阻止由该LTXID标识的事务免于在第一会话交付而强行设定未交付状态,所述事务就可以在不同的第二数据库会话中完成而并没有仍要让会话在第一数据库会话中完成的风险。即使在一个会话中执行了多项事务,服务器也可以透明地并且以标定跟多个服务器的多个会话中的多个客户端的方式向客户端提供事务幂等性。
在一个实施例中,即使事务的执行在第一次尝试期间并未完成,服务器也允许交付事件。服务器在针对数据库交付事务时保存逻辑事务标识符(“LTXID”)。这些事务可以包括例如从内部PL/SQL、从内部服务器方的Java、从远程事务、从并行事务、从分布式事务以及从不能另外利用常规手段识别的标注中利用自动交付执行的事务。服务器利用LTXID支持最多一次的执行语义以使得无论是否存在多个进行中的事务副本,由LTXID保护的数据库事务都不能重复。换句话说,客户端可以提交若干次请求以完成同一项事务,并且服务器可以避免事务被完成多于一次。
在一个实施例中,服务器阻止进行中工作的交付以确保无论停机状况如何,通过例如浏览器或中间层客户端对同一项事务的再一次提交不能交付。服务器可以通过利用针对要重新提交该事务的每一次尝试的逻辑事务ID(LTXID)记录受完成事务的不同尝试影响的事务状态而识别完成同一项事务的重复尝试。例如,当服务器在命令集已被提交供执行的情况下尝试分解命令集时,服务器可以通过将代表事务性命令集的逻辑事务ID更新为阻止状态而强行设定未交付状态。
在一个实施例中,服务器记录针对跟LTXID相关联的命令集而交付的工作。服务器可以识别工作是作为顶层调用(客户端到服务器)的一部分而交付还是被嵌入在服务器处的过程例如PL/SQL或Java过程中还是构成涉及返回其他信息例如输出赋值或返回消息的交付操作的一部分。服务器可以存储命令集具有嵌入交付状态的指示。嵌入的交付状态标识在交付完成时执行交付的整个过程尚未运行完成。交付以外的任何工作直到父过程在数据库服务器返回并且所有结果都已由客户端接收之后才能确保完成。
在一个实施例中,如果客户端请求分解提交的事务,那么服务器就识别数据库系统是超前、同步还是落后于最初的提交。服务器可以在来自客户端的事务提交序列中有间隙时拒绝客户端的请求。如果客户端尝试强行完成事务,为此服务器或客户端在LTXID序列上不同步,那么服务器可以通知客户端同步错误。
在一个实施例中,客户端驱动器设有在LTXID通过从客户端到服务器的交付调用而递增时生效的回调。回调由更高层的应用程序例如Oracle的WebLogicServer和第三方应用程序使用以记录在客户端的当前LTXID。即使是客户端的数据库会话变为不可用,客户端也可以引用当前的LTXID。
在一个实施例中,LTXID被分配以确保命名空间在全局不同的数据库以及整合为可插入架构的数据库上的唯一性。
在一个实施例中,如果在该会话中来自客户端的任意调用集合成功交付了任何工作,服务器就递增交付序列。在用于调用的返回码返回到客户端时,将包括交付编号的逻辑事务ID跟客户端共享。交付序列被用于保持会话排序。以稳定的方式更新序列允许服务器验证客户端和服务器是否同步(也就是LTXID相同)。以稳定的方式更新序列还可以允许客户端确定下一个LTXID,不过如果LTXID处理是在服务器进行那就不需要这样做。如果LTXID处理是在服务器进行,客户端可以仅存留LTXID例如用于在先前的会话变为不可用时返回给新的会话。更新序列和序列状态的永久记录允许永久记录的成长跟会话数量而不是可能大得多的事务数量成比例。跟事务成比例的成长与跟会话成比例的更加有限的成长相比可能要使用更多的空间、内存和处理功率。
在一个实施例中,即使在停机前送回客户端的交付消息并未提供这样的信息,客户端通常也可以确定停机后最后一次交付操作的输出。服务器通过强行设定用于进行中和由于停机而退回重来的事务的未交付状态来确保将交付结果送回客户端。通过使该信息对客户端可用,服务器帮助客户端避免重复的事务提交以及如果用户和应用程序尝试重新发起已经交付数据库的改变而可能导致的其他形式的“逻辑讹误(logical Corruption)”。
在一个实施例中,客户端不需要存留关联至特定数据库对象的修改编号。客户端可以通过查询逻辑标识符而不是受命令影响的对象来确定命令集是否已完成。例如,客户端可以利用LTXID查询命令集而不必考虑可能受事务性命令集影响的数据对象,从而就事务性命令集是否已经完成进行探查。
在一个实施例中,客户端无需为了确定过去提交的事务是否已交付以及这些交付是否已完成而提交另外的事务。例如,在每一次客户端提交可能会向数据库交付改变的其他命令时,客户端无需提交更新数据库中的事务历史表的DML命令。事务历史表可以在客户端提交事务性命令集时自动更新而无需客户端提交单独的语句来更新事务历史表。提交这些其他的语句将会造成服务器和客户端之间流量的明显增加。
在一个实施例中,服务器不允许客户端仅因为在客户端先前检查命令集的输出时事务性命令集尚未完成而重新提交事务性命令集。在重新执行命令集之前,服务器可以例如通过使用逻辑事务ID阻止事务历史表内的状态来尝试确定最后一项事务是否交付。如果先前会话中的另一个服务器已经更新了事务历史表来反映命令集已交付,那么第二服务器就指示客户端标识的事务已交付。换句话说,如果在更新事务历史表之前命令集已经在先前的会话中交付,那么在新会话中利用相同的LTXID重新执行的任何尝试都被交付状态阻止。但是,如果在测试事务历史表之前命令集并未在先前的会话中交付,那么先前会话中完成的事务即被阻止以使命令可以在新会话中无重复风险地重新执行。新会话中的重新执行要使用新的LTXID。如果其他的服务器在先前的会话中尝试交付事务性命令集,那么其他的服务器就会检测事务性命令集是否已被阻止以避免事务性命令集的重复执行(也就是不可预测的输出)。作为响应,其他的服务器会将已经在该会话中根据事务性命令集做出的任何改变退回重来。
在一个实施例中,服务器保持单次往返行程的事务例如使用自动交付或嵌入在PL/SQL或Java中的那些事务的状态或输出。在从客户端到服务器的单次请求中可以打开和关闭一项或多项事务。例如,客户端可以调用PL/SQL过程或Java过程以在PL/SQL或Java模块内部的几个不同的交付点向数据库交付几项不同的事务。如果交付了任何事务,用于该LTXID的往返行程的输出即被交付。当交付被嵌入在模块内,交付的输出即被记录为嵌入。当交付是用于堆栈模块的最后一次操作时,交付可以被记录或更新为完整交付。
在不同的实施例中,服务器存留远程事务和/或自主事务和/或呼出事务的输出。
在一个实施例中,服务器存留用于PL/SQL、DDL和数据控制语言(“DCL”)命令的嵌入状态或输出。
在一个实施例中,服务器检测命令集何时包括事务。在事务开始时,服务器尝试记录LTXID作为事务的一部分。如果事务已开始或已交付或已被阻止,那么服务器就避免再次尝试该项事务。如果事务已开始或已交付,那么服务器就阻止完成随后的事务。如果当前的服务器在完成或阻止事务时成功阻止了其他尝试,那么服务器就可以尝试完成事务而无需承担事务完成多于一次的风险。
在另一个实施例中,服务器检测命令集何时包括事务。在事务开始时,服务器注册LTXID以记录在COMMIT作为事务的一部分。在COMMIT,如果事务已经例如在另一个会话中被阻止,那么当前的事务即被阻止而不得提交和退回重来。
在一个实施例中,即使数据库恢复为较早版本或者在随后的数据库实体中出现故障,服务器也可以处理来自客户端的事务序列。例如,服务器可以管理会话所用的LTXID以使交付序列单调增加,并且客户端可以依赖于这种稳定特性来确定已经发送的事务性命令集所用的但是尚未收到其结果的LTXID。
在一个实施例中,服务器可以高频地处理多项事务,并在处理时记录多项事务的输出。例如,服务器可以在交付事务性命令集时更新每一个LTXID的交付编号而无需针对每一项事务创建新的LTXID。
在一个实施例中,服务器屏蔽了数据库跟客户端或终端用户交流时涉及到的停机的冲击。因为服务器存留了交付输出,当一台服务器在执行事务的时候经历停机时,另一台服务器就能够获知事务的输出。服务器可以避免停机能够以其他方式造成对用户的可见冲击、造成输入数据丢失或者造成应用程序或应用程序组件的重启,避免消耗可观的时间和资源。服务器可以屏蔽停机和交流中断而无需给应用程序开发人员增加负担。服务器软件可以无重复风险地允许将请求在系统内的其他服务器重试或安全地继续。
获知事务输出可以得到改进的终端用户体验、更高的应用程序可用性、改进应用程序开发人员处理停机的生产力并在服务器、中间层和应用程序产品之间获得更好的集成和协作。服务器的功能无需显著改变应用程序即可实现。服务器的功能可以在服务会由于停机而意外中断的多种情况下避免中断用户服务。在一个示例中,服务器提供了在按计划和意外停机以及重复提交的情况下用于最多执行一次的语义的一般性架构。服务器可以存留交付输出,针对每一项事务提升已知的预期输出,并且支持最多一次的事务执行。
图9示出了客户端利用数据库会话访问数据库的示例性结构。在示例中,客户端902利用数据库会话904A访问数据库906。客户端902可以随后检测数据库会话904A的不可用性,并且不会丢失在客户端一方的会话中建立的无法传递至数据库会话904B的状态。例如,客户端902可以在会话904B重新运行最初在会话904A执行或请求执行的命令。
在一个实施例中,即使命令不可能交付,服务器也可以提供关于命令是否被交付的指示。例如,客户端可以请求命令集的输出,即使该命令集被部分或全部执行也不能完成事务。在通过阻止命令集强行设定输出后,服务器可以通过指明命令集并未完成事务来答复请求,和/或服务器可以指明无论命令集是否完成该命令集都不可能完成事务。服务器还可以向客户端指明在服务器一方关于命令集的进程,其中明确了哪些命令已执行或尚未执行。
在一个实施例中,本应响应于命令集从服务器发送至客户端的结果如果确实被发送则应包括客户端能够依赖于客户端一方操作的数值。如果客户端针对尚未返回这种数值的命令请求输出,那么即使在命令集中没有尚未完成的事务,客户端也可以接收到命令尚未完成的指示。在接收到对命令输出的请求之后,服务器可以确定结果本应包括这样的数值并且向客户端指明命令集尚未完成,直到由客户端接收到该数值为止。在执行命令时本应由服务器返回并且依赖于客户端的数据可以有多种类型,包括事务跟踪信息,在执行命令时是否出现了任何错误(并且可能是错误列表),客户端明确请求(根据选择或输出赋值返回)的其他数据和/或自动返回的数据例如受命令影响的行号。其他类型的信息例如事务当前是否打开可能并不依赖于客户端,并且客户端可能无法接收到该信息的事实并不能阻止服务器向客户端指明命令集已经完成。其他类型的信息尽管并未返回客户端也仍然可以保存在数据库内以用于在新建立的会话中返回给客户端。为了向客户端指明命令集已经完成,也可能并不需要保存的信息。
在一个实施例中,服务器可以将尚未返回给客户端的结果返回。如果服务器在新建立的会话中返回客户端本应依赖的结果,那么即使是在先前的会话中并未范围结果,服务器也可以随后在新建立的会话中将命令集作为完成处理。
在一个实施例中,命令集可以包括对会话状态做出明确改变的命令。例如,命令可以改变应该用于会话的语言。如果客户端针对改变会话状态的命令请求输出,那么如果该会话状态未存留在数据库内则客户端就可以接收命令尚未完成的指示。在接收对输出的请求时,服务器可以确定命令集本应改变会话状态并且直到在新建立的会话中对会话状态实施了改变之前都向客户端指明命令集仍未完成。
在一个实施例中,服务器可以对会话状态实施尚未完成的改变。如果服务器在新建立的会话中实施本应在先前的会话中若完成了命令就应实现的改变,那么即使在先前的会话中并未实现改变服务器也可以在新建立的会话中将命令作为完成处理。
在一个实施例中,服务器可以跟踪本应通过在从客户端到服务器的单次请求中提交的命令促使的多项事务。例如,服务器可以将基于针对命令的执行计划或者基于服务器已知用于促使事务的命令而预测要执行的事务编号。用这种方式,即使单个命令集促使了多项事务也可以跟踪针对每一项独立事务的交付输出。在本实施例中,服务器可以在针对包括多项事务的请求逐项事务处理的基础上而不是在逐项请求处理的基础上向客户端提供事务输出。在一个特定的示例中,客户端可以针对请求来请求事务输出,然后服务器可以通过提供用于多项事务的多个事务输出来响应,如果请求被执行完成就能促使或者就应该促使所述的多项事务。服务器可以报告个别事务的完成而不是将全部事务作为整体来报告,并且服务器可以阻止个别未交付事务而不是将所有的未交付事务作为整体来阻止。通过由服务器阻止并报告未交付状态来强行设定未交付状态可以是对来自客户端的识别促使了多项事务的命令集的信息请求的响应,或者通过识别命令集内的特定事务来完成。
在一个实施例中,响应于来自客户端的关于通过LTXID识别出的事务的信息请求,服务器可以确定执行由LTXID标识的交易的过程已死、确保无法完成或者预测为无法完成。在一个示例中,服务器可以通过借助负责用于执行由该LTXID标识的交易的其他组件进行校验来完成该确定。在本实施例中,即使服务器尚未阻止事务,服务器也可以向客户端报告事务已确保无法完成。
执行事务性命令
一种示例性数据库管理系统(DBMS)例如ORACLE、例如很多其他的DMBMS通过包括ORACLE的OCI驱动程序和ORACLE的JDBC驱动程序在内的各种客户端驱动程序接口为应用程序编写人员提供了基于事务的编程模型。通过驱动程序,顶层的SQL和PL/SQL调用建立起会话中的事务状态和非事务状态。在示例性系统中,客户端驱动程序向关系数据库管理系统(RDBMS)发送SELECT、PL/SQL、ALTER SESSION、DML和TRUNCATE语句并且在事务结束时交付改变。交付可以在用于服务器的同一个往返行程内进行,或者也可以在单独的往返行程内进行。
图1更加详细地示出了示例性系统中的不同组件和层。系统支持状态构建和交付处理。参照图1的工作流步骤,在登录阶段112,客户端发出调用以跟数据库系统104-110相连接。在登录阶段112,客户端驱动程序102完成认证握手并且建立客户端一方的会话句柄。在步骤116建立跟数据库系统的连接。在无事务阶段118,客户端102在步骤120中向RDBMSSQL层106发送SQL和PL/SQL命令。在122阶段,RDBMS SQL层106分析、关联并执行命令120。RDBMS SQL层106编译每一条语句并向SQL引擎或PL/SQL引擎发送请求。在步骤124执行命令120建立起用于会话的非事务性状态。在步骤126,服务器向客户端返回结果集合、输出关联、DML返回结果和ORACLE消息。这些结果的一部分被存留在客户端驱动程序内并传输至应用程序。
在有数据库事务的阶段128,客户端102在步骤130向RDBMS SQL层106发送DML命令以及包含DML的PL/SQL命令。在132阶段,RDBMS SQL层106分析、关联并执行命令130。SQL层编译每一条语句并向PL/SQL引擎和DML驱动程序发送请求。在步骤134执行命令启动一项或多项事务并且在步骤136建立RDBMS事务层108处的会话状态和事务状态。DML操作结果或ORACLE出错信息在步骤138返回给客户端102。
在交付工作阶段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消息。
在一个实施例中,客户端在身份验证时、在校验时以及在每一次事务或事务性命令集成功交付时接收逻辑事务ID,此时要接收对事务性命令集的确认。在一个实施例中,例如在前台过程或数据库实例崩溃或网络故障或出现任何一种异常终止的情况时,客户端驱动程序和DBMS之间就存在停机。客户端接收出错信息并且服务器一方的事务性和非事务性状态丢失。如果针对DBMS的最后一次通信是交付请求142或者可能包含交付请求,那么使用现有系统的应用程序在应用程序发送交付请求之后就无法获得交付输出。交付可能已经完成或者也可能并未完成,这取决于停机出现在哪个位置。例如,因为操作可能是在查询之后立刻交付,所以应用程序可能不知道交付消息丢失与否,并且应用程序无法安全查询最后一次交付请求的输出并恢复丢失的交付消息。
如果客户端已经进入工作并且在停机之前将该工作提交至服务器,那么客户端处的状态在停机之后得以保持,可能具有输入数据、返回数据和缓存的变量。应用程序需要以此运行的非事务性会话状态在现有的系统中丢失。如果事务已经开始并且交付尚未发出,那么进行中的事务就退回重来并且需要重新提交。如果事务已经开始并且交付也已发出,那么送回客户端的交付信息在现有的系统中无法持久。使用现有系统的客户端变成无法获知事务是否交付。
在现有的系统中,送回客户端的交付信息无法持久。如果在客户端和服务器之间有中断,那么客户端就会看到指示通信出错的错误信息。这种报错不会告知应用程序提交是否执行了任何交付操作,或者过程调用是运行完成了所有预期交付的执行和会话状态的改变还是中途出错或者甚至是在从客户端断开后仍保持运行。
应用程序开发人员可以写入自定义代码以在停机之后重新连接,但是应用程序没有用于将停机之间建立起来的非事务性会话状态重新建立或者尝试测试服务器以确定提交的工作是否交付或需要重复的机制。任何代码模块都有可能出错,并且应用程序开发人员不能在每一个交付点都执行这种形式的错误处理以确定指定的事务是否交付以及要恢复哪些状态以继续。应用程序可以利用应用程序和服务器之间的附加带宽写入修改编号或存储其他的一致信息以备能够查询。使用这些附加带宽是不合需要的,并且存留修改编号在按年月日排序方面以及在有故常而重定向至不同的数据库时也不安全。在没有主关键字或修改编号时,应用程序无法为了改变-跟踪而进行查询并且查询自身的方法是有根本缺陷的,原因是查询的内容可能在查询之后立刻交付。另外,对于提交包含多次交付的工作的批次管理程序,如果工作并未存留若重新提交就重启的位置记录,那么工作的重新提交就是不可行的。
通过应用跟踪应用程序的数据而提交的查询无法披露事务是否已经完成,原因是事务可能在该查询执行之后立刻交付。实际上,在通信出错之后,服务器仍然可能运行提交而并未意识到客户端已断开。对于PL/SQL或Java命令,没有用于过程提交的关于提交是运行完成还是中途异常终止的记录。尽管过程中的命令可能已经交付,但是针对该过程的后续工作可能仍未完成。
应用程序也不能跟踪本地事务、远程事务、分布式事务、并行事务、重复事务和XA事务。即使应用程序在特定的情况下能够确定在特定故障之前要执行哪些命令,重建在应用程序生存期内建立起来的非事务性会话状态对于在运行时修改非事务性会话的应用程序来说也并不简单。
无法识别出最后一次提交是已经交付还是应该在随后的某一时刻交付还是并未运行完成能够由于用户和软件可能尝试重新发起已经存留的改变而导致重复的事务提交和其他形式的“逻辑讹误”。
如果丢失的会话被再次提交,那么只要系统允许,重新提交就能够保持原子性和一致性。但是,如果针对事务建立的非事务性状态不正确或者如果事务已经交付,那么事务就不能被准确地重新提交。在现有的系统中,服务器和客户端之间的读操作没有幂等性。在缺少幂等性的情况下,重新提交能够导致事务的应用多于一次。
检测数据库会话的不可用性或超时
作为一个示例,客户端可以在客户端从用于在会话中执行的最新命令集接收结果之前或之后检测数据库会话的不可用性或超时。在一个实施例中,在客户端发送用于在数据库会话中执行的命令集之后,客户端才接收到数据库会话已无效的通知。作为响应,无论命令集是否执行,客户端都可以尝试阻止命令集。客户端可以可选地尝试在新的数据库会话中重新运行命令集。如果客户端选择在新的数据库会话中重新运行命令集,那么提供新数据库会话的服务器即可避免事务重复。例如,服务器可以避免重新执行已经在初始对话中执行过的命令。服务器也可以在新会话中重新运行事务之前阻止事务的执行。
在一个实施例中,监测逻辑接收指示数据库会话以变为应用程序不可用的信息。例如,信息可以指示数据库实例已出错或就要出错,或者由数据库示例提供给应用程序的服务或其他资源已出错或就要出错。作为另一个示例,信息可以指示数据库实例已经无法在至少阈值时间量内做出响应(也就是说实例已超时)。数据库会话的不可用性可以缘于计划内或意外的停机。对于计划内停机,即使数据库会话可能仍然可用,由监测逻辑接收的信息也指示停机是计划内的。指示计划内的“宕机”或停机允许在会话出故障和恢复之前完成工作。实际上,在使用连接池时,如果所有工作已完成,因为应用程序请求已经完成,所以就不需要恢复会话。相反,如果使用指定会话,重新运行就将会话转移至另一个实例以允许计划内的停机。在一个实施例中,数据库实例可以实现为对一种服务不可用但是对另一种服务可用,目的是为了降低数据库系统内的实例负荷。监测逻辑可以从记录原始数据库会话可用性的任何代理程序或组件接收信息。监测逻辑可以通过关闭数据库会话(例如由不可用数据库实例服务的会话)、打开新的数据库会话(例如由新的数据库实例服务的会话)并且在新的数据库会话中促使重新运行先前在现已不可用的数据库会话中发送的命令而对信息做出响应。在以这种方式用于“分配”工作时,重新运行应该位于负荷较小的数据库实例。
在一个实施例中,监测逻辑每一次检查数据库会话是否可用,应用程序都提交用于在数据库会话中执行的命令。因此,检测数据库会话是否已变为不可用可以随着接收要在数据库会话中执行的命令而同步进行。如果接口关闭那这种技术就可供使用。如果节点或网络故障,那么直到保持有效的TCP/IP过期之后才能接收到错误。
在一个实施例中,用于监测的有效技术是跟命令异步地接收快速应用程序通知(“FAN”)事件。FAN事件无论会话是否可用都有助于消除报废代码的路径校验并消除等待有效TCP的需求。
FAN监测逻辑订制向订购者发布可用性信息的服务。例如,监测逻辑可以在快速应用程序通知(“FAN”)事件中接收更新信息。通过快速通知借此公布很多事件用于系统状态变化的改变,应用程序就能够快速恢复并且会话也能够快速地重新平衡。在跟服务相关联的资源经历输出改变例如终止或启动/重启时,通知事件被立刻公布以供该事件的各种订购者使用。例如,通知事件在数据库实例变为可用或不可用时或者在实例中的服务变为可用或不可用时发出。通知事件包含使订购者能够根据匹配会话签名来识别受输出改变影响的特定会话的信息并由此做出响应。这就允许在资源无效时快速地放弃会话并快速终止正在进行的处理,还允许在资源重启时快速地重新平衡工作。
通知事件针对用于服务以及支持服务的资源例如特定实例、实例、节点或数据库集群的输出改变而出现。在由一个或多个实例提供的服务开始时,发出可以用于启动依赖于该服务的应用程序的通知事件(UP)。在由一个或多个实例提供的服务终止时,还有在实例、节点或网络终止时,发出停止相关应用程序的通知事件(DOWN)。在管理集群软件因为服务已经超过其故障阈值而不能再管理服务时,发出中断重试服务的应用程序的通知事件(NOT_RESTARTING)。在一个实施例中,NOT_RESTARTING事件启动到灾难服务的切换。
在连接至集群之后,唯一性的签名(也就是定位器)被生成用于相关会话并记录在句柄上作为连接的一部分。在一个实施例中,签名包括服务标识符、节点标识符以及数据库唯一名称和实例标识符,其中的每一个都跟会话相关联。在数据库集群的背景下,通知事件包含使订购者能够识别受输出改变影响的特定会话的信息也就是受影响会话的签名。对于某些事件类型,用于识别受影响会话的信息包括跟输出改变相关联的服务和数据库的标识符。对于另一些事件类型,用于识别受影响会话的信息还包括跟输出改变相关联的实例和节点的标识符。受影响的会话是签名跟事件有效负载内包含的签名相匹配的会话。
在各种实例中,检测之后存在不同的能够开始重新运行的时间点。监测逻辑可以从FAN事件接收信息,清除无效会话,但是并不立刻启动重新运行。例如,在接收到在已知要成为不可用的会话中执行的命令后,驱动程序建立新会话,在其中重建针对先前不可用会话而存在的客户端状态。在另一个实施例中,驱动程序可以响应于检测到不可用性而启动重新运行。
在一个实例中,监测逻辑响应于接收到要在已经变为不可用的数据库会话中执行的命令而触发在可用的数据库会话中重新运行。在本实施例中,监测逻辑可以检测到数据库会话已变为不可用而无需恢复数据库会话。例如,在数据库会话已变为不可用之后,如果没有更多的命令在该数据库会话中执行,那么就没有必要重新运行。在一个实施例中,监测逻辑通过FAN或接收到的错误获知会话不可用。如果存在运行中的命令那就调用重新运行,或者如果没有运行中的命令,那就在应用程序发送下一条命令时调用重新运行。如果应用程序再也不发送命令,那么重新运行就不会发生。
在另一个实例中,重新运行逻辑在接收到要在不可用的数据库会话中执行命令之前就触发在可用的数据库会话中重新运行。用这种方式,数据库会话可以在应用程序对数据库会话提交任何其他的命令之前就得到恢复。在接收到要在数据库会话中执行的另一条命令后,监测逻辑应该已经促使重新运行开始或完成以恢复数据库会话。因此,新接收到的命令由于只需会话即可重新运行而能更加高效地运行。
存留逻辑事务标识符(“LTXID”)
逻辑事务ID是全局唯一的ID,从应用程序的角度唯一性地定义了数据库会话。逻辑事务ID被存储在OCI会话句柄以及用于瘦JDBC驱动程序的连接对象内。逻辑事务ID是幂等性语义的基础。
用户通过数据库服务连接。为了实现最多执行一次的语义而向服务定义中加入新属性。该属性被称作commit_outcome。如果针对服务设定了该属性那就要创建逻辑事务ID;否则就要存留pre-12c特性。以下的说明介绍了用于创建和存留逻辑事务ID的示例性步骤。
应用程序通过对应的驱动程序连接至数据库。在驱动程序连接至数据库时就启动新的数据库会话。作为会话创建的一部分还创建了新的逻辑事务ID(LTXID)。逻辑事务ID仅创建并存储在内存中的用户会话结构内并随后返回给客户端驱动程序。逻辑事务ID尚未存储在事务历史表内。新的逻辑事务ID被返回给驱动程序并且用户能够查询会话句柄已获取逻辑事务ID的值。逻辑事务ID以交付编号0开始。如果仅仅读取,那么LTXID不会改变。这是例如有效数据保护和只读数据库的情况。
如果应用程序使用连接池,那么连接池已经在服务器端和客户端的会话中存留了逻辑事务ID(LTXID)。在从池中校验时,应用程序使用会话中经其校验过的LTXID。该LTXID在最后一次登记时将交付编号返回连接池。
在一种示例性方法中,服务器接收用于在会话中执行的命令集。服务器会话已经存留了在身份验证时传输给客户端或者客户端在校验时包含的LTXID。一条或多条命令的集合如果在会话中完成就会促使执行:启动事务的第一服务器操作和交付事务的第二服务器操作。在该实例中,服务器确定命令集中是否包括至少一条如果执行就会启动至少一项事务的命令。响应于确定命令集包括至少一条如果执行就会启动至少一项事务的命令,服务器更新用于LTXID的存储信息作为交付操作的一部分。在一个实例中,服务器执行的服务器操作包括交付改变以及向事务历史表中插入或更新存储信息已指示命令集中的至少一项事务已经利用该LTXID交付。在交付后,新的LTXID生成并且在用于交付信息的返程中返回给客户端。
在一个实施例中,服务器存储的事务历史表包括用于会话中接收到的多个事务性命令集中的每一个事务性命令集的表项。服务器可以通过向用于命令集的事务历史表中增加表项来更新存储的信息以指示事务已经在命令集中开始。
图14示出了用于存留事务性命令集记录的示例性方法。在步骤1402,服务器接收用于在会话中执行的命令集。例如,服务器可以接收命名由服务器执行的一条或多条命令的序列的请求。在步骤1404,服务器确定命令集中的命令如果执行那是否会启动至少一项事务。如果命令并未启动事务,那么服务器就在步骤1406确定命令集是否包括任何其他的命令。如果答案为是,那么服务器就针对第二条命令重新执行步骤1404。如果服务器从未收到启动事务的命令,那么在步骤1408服务器就完成命令集的执行而无需注册或更新命令集所用的事务性信息例如LTXID。在另一个实施例中,即使命令集中没有事务,服务器也存储对LTXID的临时更新,但是除非服务器检测到事务或者要执行的潜在事务,否则临时更新并不交付。
另一方面,如果服务器确定命令集中的下一条命令若执行就会启动事务,那么服务器就在步骤1410注册成若该事务交付就要记录LTXID。服务器继续执行命令集,直到在步骤1412交付了开启的事务为止。在交付时,如果LTXID是第一次被看到,那就插入该LTXID。否则就更新LTXID。在一个实施例中,服务器在每一次交付时利用更新的LTXID记录命令集内的每一项交付事务。在另一个实施例中,服务器仅记录命令集中是否存在至少一项交付的事务。在交付开启的事务后,服务器在步骤1414插入或更新LTXID以指示开启的事务已交付。在交付后,在步骤1416生成下一个要使用的LTXID并返回至客户端。
逻辑事务标识符(“LTXID”)唯一地定义了事务性命令集并且用于确定是否交付了最后一项事务并且如果确已交付那么交付是否已完成。逻辑事务标识符可以包括用于数据库和实例的特有域,目的是为了检测故障是针对相同还是不同的数据库。包含这种域的逻辑事务标识符被称作“全局唯一”。接下来要使用的逻辑事务标识符由服务器端存留在每一个服务器端的会话中。事务标识符还可以包括用于实例、会话、版本和/或服务的特有域。在一个实例中,逻辑事务标识符被传输至并存留或储存在调用接口(“OCI”)会话句柄或ODBC或ODP.Net会话句柄或者来自瘦JavaTM数据库互连(“JDBC”)驱动程序的连接对象内。客户端存留服务器计划要使用的下一个逻辑事务ID的副本。
在一个实施例中,系统根据逻辑事务标识符阻避免事务的重复执行。重复执行可以在交付时进行检测。在本实施例中的每一个交付点,如果事务已经交付就会违反服务器内的约束条件校验。如果是这种情况,那就放弃交付并且将事务退回重来。如果不是这种情况,交付就继续进行。允许交付继续进行就阻止了利用相同的LTXID交付事务的后续尝试。LTXID可以在交付时存储或更新。在交付之后,服务器计划针对该会话使用的下一个LTXID的副本被返回给客户端。
在停机后,客户端能够连接至服务器。然后使用来自先前连接的LTXID就能测试最后一项事务的输出。如果该事务并未交付,那么服务器可以阻止该LTXID以禁止使用该LTXID的在重新运行之前激活的先前运行中事务交付。如果LTXID已经交付或者如果LTXID先前被阻止,那么阻止LTXID的尝试可能会失败。
在一个实施例中,用于会话的当前LTXID描述了要在会话中交付的下一项事务。当前的LTXID可以已某种可预测的方式例如通过递加先前的LTXID来根据先前的LTXID计算。在服务器向客户端发送跟先前LTXID相关联的事务已交付的通知时,服务器向客户端输送服务器计划使用的下一个LTXID。
在一个实施例中,LTXID包括:
·版本
·数据库标识符
包括用于统一数据库的可插入数据库标识符
·数据库实例标识符
·逻辑会话编号(GUID)
·交付编号
·服务器标识符
在各种实施例中,LTXID可以被用于针对以下情况支持最多执行一次的语义:
本地事务
自主事务
交付成功(自动交付)
只读性事务
循环性事务
分布式和远程事务
并行DML
作业调度事务
XA事务
逻辑会话编号(GUID)在会话建立时自动分配。在一个实施例中,GUID是应用程序无法读取的不透明结构。在一个实施例中,GUID针对事务历史的有效期是唯一的。
在一个实施例中,为了可量测性,运行的交付编号在交付数据库事务时增加。对于事务管理程序例如WebLogic来说可以明确一种附加属性。该属性被用于WebLogic服务器或Tuxedo或其他事务管理程序自身的全局事务标识符(“GTRID”)并且通常能够用于描述XA事务。
在一个实施例中,逻辑事务ID消除了重复事务的可能性。利用逻辑事务ID消除重复事务的可能性被称作自动事务幂等性。逻辑事务ID在交付时存留并且在退回重来后重新使用。在正常运行期间,LTXID被自动存留在客户端和服务器处用于每一项数据库事务的会话中。在交付时,逻辑事务ID被存留作为交付事务的一部分。
在一个实施例中,为了支持最多一次的协议,RDBMS在同意用于重试的存留期内存留逻辑事务ID。默认存留期是24小时。客户可以选择将该时段扩展至一周或更长,或者根据需要缩短该时段。存留期越长,利用旧LTXID阻止旧会话以免重新运行的最多一次的校验就持续得越长。在调用多个RDBMS时,就像在使用Data Guard和Golden Gate的情况,逻辑事务ID被复制到调用的每一个数据库。
在一个示例中,为12c ORACLE JDBC(瘦且为OCI)和OCI客户端提供的getLTXIDAPI允许应用程序拥有检索该会话要使用的下一个逻辑事务ID的能力。GET_LTXID_OUTCOMEPL/SQL程序包允许应用程序利用获取的逻辑事务ID确定动作的输出。GET_LTXID_OUTCOME程序包可以包括阻止LTXID免于交付以使得例如在使用该LTXID的事务运行中时输出是已知的。GET_LTXID_OUTCOME在尝试重新运行之前调用并且可供各种应用使用以包含在它们的应用程序中。如本文所用,GET_LTXID_OUTCOME和FORCE_OUTCOME能够可互换地使用以供引用具有该功能的程序包。在一个实施例中,封装返回事务是否交付、事务是不是完整的用户调用以及LTXID是否被阻止。
在一个实施例中,逻辑事务标识符到数据库事务的映射被存留在事务历史表内。对于指定的会话,在服务器执行会话中命令集内的COMMIT或最后一次COMMIT时,服务器可以插入若为第一次使用的LTXID或者更新当前的LTXID。插入或更新被存储在事务历史表内,在停机情况下可供其他的会话和服务器使用。
在一个实施例中,服务器在事务开启时执行回调以创建或更新LTXID。服务器在生成重做(redo)时插入第一次的取值,并且服务器以可预测的方式更新随后的取值。服务器在交付时也可以执行回调以创建或更新LTXID。在磁盘上的redo稳定之后,服务器可以将LTXID内的交付编号加一或者用某种其他的可预测或确定性的方式来更新交付编号。服务器可以在会话句柄上将交付编号的增量或其他更新跟交付输出一起返回。
在一个实施例中,用户连接至数据库并创建新的数据库会话。如果跟用户会话相关联的数据库服务具有“commit_outcome”属性设置,那就针对该会话创建新的逻辑事务ID(LTXID)。例如,RDBMS内核调用创建LTXID函数以将创建新的逻辑事务ID作为创建新的用户会话的一部分。逻辑事务ID此时仅存储在内存中而尚未存留。LTXID通过会话句柄返回给客户端。逻辑事务ID是唯一的,并且在同一集群或全局结构的数据库集合中的不同数据库实例上不能创建相同的逻辑事务ID。
在一个实施例中,LTXID仅针对处理SQL的用户会话创建。它们并不针对后台会话创建。它们并不针对由任务使用的从属过程例如内存监测程序(“MMON”)创建。在用于并行DML的实例中,只有并行协调程序具有相关联的LTXID。在用于作业调度程序的实例中,LTXID被管理用于在作业调度从属程序中运行的作业。
在一个实施例中,LTXID仅在使用支持LTXID的客户端时创建。支持LTXID的示例性客户端包括OCI、瘦JDBC和JDBC OCI、OCCI以及ODP.Net客户端。通过在会话所连接的服务上设置所谓的COMMIT_OUTCOME来进行配置。
在一个实施例中,如果在验证用户时设备上设置了commit_outcome属性,那就针对用户会话创建和管理LTXID。如果commit_outcome属性在连接之后设置,那么针对该会话就不在COMMIT处跟踪LTXID。如果commit_outcome被设定为FALSE,那么支持LTXID的现有会话就继续支持LTXID。
在一个实施例中,如果创建会话请求没有成功完成并且用户重试该操作,那就生成新的逻辑事务标识符。在本实施例中,旧的逻辑事务标识符不再重新使用。
在一个实施例中,LTXID上含有数据库的唯一名称和实例编号。利用LTXID接收事务输出请求的服务器可以识别原始数据库和实例,其中的事务利用作为LTXID一部分的数据库和实例标识符来提交。
图8示出了用于保存数据库系统内的事务状态的示例性方法的各个阶段。新的会话在步骤812开始。在该实例中,只要事务不发生任何改变,服务器就以典型的方式运行。当应用程序在步骤814发出创建首次redo的第一次改变之后,在步骤816注册两种交付回调:交付前回调和交付后回调。在事务交付时,交付前回调和交付后回调被自动调用。在步骤818,在事务于步骤820交付至磁盘之前调用交付前回调。在步骤822,在事务交付至磁盘之后调用交付后回调。
在一个实施例中,服务器在事务已交付且执行的COMMIT语句在PL/SQL或Java模块内嵌套或者是来自这些模块和函数的返回语句时将事务性命令集的输出设定为EMBEDDED(已嵌入),COMMIT语句在存储Java的过程中嵌套,或者COMMIT语句通过返回附加信息的调用来执行。返回处理行号的AUTOCOMMIT模式以及能够在包括事务中的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。
在一个实例中,DDL命令作为依赖于DDL命令的递归和顶层的COMMIT组合而执行。COMMIT执行的编号和执行的层级都是DDL专用的。在实例中,如果DDL命令中出现任何交付,那么DDL命令就递加LTXID。用于LTXID的COMMIT输出在运行至完成时被更新为COMMITTED。根据DDL命令执行的中间COMMIT具有的中间COMMIT输出为EMBEDDED。在一个特定的实例中,DDL命令将LTXID准确地递加一。换句话说,在该特定实例中,无论COMMIT的编号如何,具有递归COMMIT的命令集都超前LTXID恰好一步。在另一个实施例中,LTXID以某种其他的能够跟客户端共享的一致或可预测的方式改变。这就确保了LTXID交付序列在到服务器的任何往返行程中都跟客户端同步。
下表示出了命令结构以及用于存留LTXID的对应过程的几个示例。
利用LTXID针对事务获取输出
在一种示例性方法中,服务器在第二会话中从客户端接收用于由客户端在第一会话中发送的输出或命令集输出的请求。请求例如通过使用第一会话所用的LTXID来识别这些命令。命令集如果在第一会话中完成就促使执行开启事务的第一服务器操作、交付事务的第二服务器操作并且针对第二操作对客户端做出响应以向客户端报告一条或多条命令的集合已交付。直到第二操作已交付事务之后才向客户端报告命令集的完成。在本示例中,服务器确定命令集内是否还有任何已交付的事务。至少部分地基于确定命令集内没有任何已交付的事务,服务器向客户端发送对输出请求或输出的响应以指示命令集可以作为未交付来处理。
在另一种示例性方法中,服务器从客户端接收对于由客户端在会话中发送的命令集输出的请求。命令集如果在会话中完成就促使执行开启事务的第一服务器操作、交付事务的第二服务器操作并且针对第二操作对客户端做出响应以向客户端报告一条或多条命令的集合已交付。直到第二操作已交付事务之后才向客户端报告一条或多条命令的命令集的完成。在本示例中,服务器确定命令集内是否还有至少一项已交付的事务。至少部分地基于确定命令集内有至少一项事务已开始且已交付,服务器向客户端发送对请求的响应以指示命令集内有至少一项事务已交付。服务器还可以报告来自客户端的包括该交付的最终调用是已完成还是部分完成(嵌入)。
在一个实施例中,客户端在会话中向服务器发送命令集,其中该服务器会话被设置用于记录应该有事务交付的LTXID。相同或不同的服务器从客户端接收对输出的请求以供事务在另一个不同的会话中使用该LTXID。例如,第一服务器可能在执行命令集时故障,并且客户端可能在跟第二服务器或同一服务器的第二会话中故障。即使第一服务器从未报告过命令集的结果,服务器也可以在第二会话中请求先前在第一会话中通过使用LTXID发送的命令集输出。
在一个实施例中,客户端请求单条PL/SQL命令的输出,该命令如果在会话中完成将促使执行除了开启事务的第一服务器操作以外的几项服务器操作、交付事务的第二服务器操作以及针对该第二操作送往客户端的向客户端报告一项或多项事务的集合已完成的响应。服务器操作可以包括开启事务的操作和交付事务的操作。在一个实施例中,命令集如果在会话中完成将促使在第一服务器操作和第二服务器操作之间执行至少一项服务器操作。例如,至少一项服务器操作可以对数据库内的数据库对象做出临时改变,并且第二服务器操作如果在会话中完成则可以将临时改变跟LTXID和该LTXID的嵌入或完成的输出一起交付。在另一个实例中,开启事务的第一服务器操作是如果执行就促使服务器做出临时改变的操作。
在一个实施例中,处理请求的服务器是在多个会话中提供对数据库访问的服务器或多个服务器实例。在某些实施方式中,每一个会话同时被分配给最多一个服务器。在一个实例中,通过客户端在会话中发送命令集之前,服务器可以在会话中为客户端提供对数据库的访问并且该访问包括如果交付事务就会使用的下一个LTXID。如果在命令集已通过客户端在会话中发送之后会话变为对客户端不可用,那么客户端可能无法获知命令集或命令集内的事务究竟是尚未开始、部分交付、已交付还是运行完成。在一个实施例中,客户端可以通过新的服务器在新的会话中请求命令集的输出。在跟客户端的另一个会话中,另一个服务器可以通过输送来自先前会话的LTXID来提供初始会话中由客户端发送给初始服务器的命令集输出。
在一个实施例中,对事务输出的请求根据调用LTXID的标识符识别命令集,LTXID是唯一地针对会话发送的多个命令集中的一条或多条命令的一个命令集。在一个实例中,用于一个命令集的标识符(逻辑事务ID-LTXID)可以根据先前发送命令集的LTXID来生成。在一个特定的实例中,LTXID的一部分随着由服务器交付不同的命令集而递加。在一个实施例中,在由服务器交付任何新的命令集之后就分配新的标识符。这是应用于要交付的下一项事务的下一个LTXID。在另一个实施例中,新的标识符仅被分配给包括至少一项事务的命令集或“事务性命令集”。用这种方式,标识符在多个事务性命令集中唯一性地识别某个事务性命令集。
在一个实施例中,标识符在会话发送的多个命令集中唯一地针对某个命令集并且在多个服务器对数据库提供访问的多个会话中唯一地针对某个会话。例如,标识符唯一地针对本地和全局数据库中的某项事务。
在一个实施例中,通过在送往客户端的不同消息中附带用于由该客户端提交的下一项事务的下一个标识符来向客户端包括不同命令集的交付。客户端并不返回该标识符。只要客户端发出另一个交付操作,服务器会话就已存留好标识符备用。不同的消息可以包括不同命令集的不同结果集合以及下一个LTXID。只要来自客户端的最终调用包括采用客户端存留的先前LTXID的一项或多项交付操作,LTXID就随命令的结果一起返回。对于同步来说最重要的是返回客户端的LTXID包括单调增加的嵌入交付编号以捕捉来自客户端的调用序列中的间隙。
在一个实施例中,服务器响应于确定命令集中有至少一项事务已交付而阻止在第一会话中发送的命令集的完成。在本实施例中,对请求的响应可以指示命令集被阻止以免在第一会话中完成而是安全地用于在第二会话中完成。服务器可以在第二会话中完成阻止的命令集或者向用户返回第一会话的结果或者采取某种其他的动作。
在一个实施例中,在第一会话中执行命令集的第一服务器完成开启事务的第一服务器操作。第一服务器操作使得为了交付事务而交付LTXID。在完成至少一项事务之前,第二服务器可以在第二会话中接收利用在第一会话中发送的LTXID来识别命令集的请求。第二服务器通过使用跟第一会话相关联的LTXID在存储的信息例如事务历史表中查询输出或事务输出来确定至少有一项事务尚未交付。
在一个实施例中,服务器通过插入或更新用于先前会话LTXID的存储信息来阻止第一会话中发送的命令集的完成,由此指明命令集已被阻止以免在第一会话中完成。如果原始服务器尝试在第一会话中完成命令集,那么就会在交付时出现对约束条件的违反并且事务要退回重来。一旦LTXID被阻止,这就允许另外的服务器在新的服务器和会话中完成命令集并通过用于新会话的LTXID更新存储信息以指明命令集已交付。如果存储的信息不允许另外的服务器在第一会话中完成命令集,那么另外的服务器可以在第一会话中退回重来或者放弃尚未完成的改变。
图10示出了利用LTXID确定事务性命令集输出的示例性方法。在步骤1001,客户端首先在身份验证、池中的连接校验或由于交付操作而从服务器更新时从服务器接收并存留LTXID。在步骤1002,第一服务器从客户端接收用于在现有会话中执行的事务性命令集。在步骤1004,客户端未接收到事务性命令集已完成的报告。由于未收到这样的报告,因此客户端通常无法获知事务性命令集的输出。在该实例中,客户端通过先前的会话访问旧的LTXID。位于相同或不同服务器的第二会话随后在步骤1006利用该过去的LTXID从客户端接收对事务性命令集输出的请求。在步骤1008,第二服务器确定是否已经交付了事务性命令集中的至少一项事务。如果事务性命令集中的所有事务均已交付,第二服务器就在步骤1012向客户端发送响应以指明命令集可以作为已完成或已交付来处理。如果存在交付后还有更多工作的可能性,那么响应就在步骤1014指明命令集可能是部分交付或EMBEDDED,或者客户端不能安全处理,就像没有待决工作还要完成一样。可选地,如果未利用该LTXID交付事务,那么第二服务器可以阻止用于该LTXID的事务性命令集的完成,和/或向客户端指明命令集无法在现有会话中完成,正如图10的步骤1010或图11的步骤1112所示。如果命令已被阻止,第二服务器可以如步骤1114所示选择执行事务性命令集,或者如步骤1116所示选择向用户返回结果并且出除了向客户端指明命令已被阻止之外不再有其他动作。
在一个实施例中,命令集的输出是COMMITTED、EMBEDDED、FORCED或者包括SERVER_AHEAD或CLIENT_AHEAD的出错输出的一种。如果在命令集中没有留下未执行的COMMIT,那么命令集的输出就是COMMITTED。如果已经执行了一个或多个COMMIT但是命令集中仍然留有未执行的COMMIT或者有工作要完成例如要返回结果的输出参数,那么命令集的输出就是EMBEDDED。如果服务器在一次或多次完成命令集失败后尝试完成命令集,那么命令集的输出就是FORCED。如果客户端请求命令集的输出而不是最新的命令集,那么输出就可以是SERVER_AHEAD。最后,如果服务器是由LTXID中的交付序列标识的客户端后台的一次或多次LTXID调用,那么输出就可以是CLIENT_AHEAD。也可以向客户端返回其他的跟命令集处理相关的具有不同详细程度的输出,包括单独或分组处理命令集内的任何COMMIT。
针对LTXID使用FORCE_OUTCOME的输出
在另一个实施例中,公共接口提供了具有一个输入参数LTXID以及两个返回参数COMMITTED(取值为TRUE或FALSE)和USER_CALL_COMPLETED(取值为TRUE或FALSE)的GET_LTXID_OUTCOME,还有错误代码,其中包括在(通过调用GET_LTXID_OUTCOME)请求LTXID的输出时用于SERVER_AHEAD和CLIENT_AHEAD的错误。如果交付了命令集内的任何命令,那么事务结果即被确定为COMMITTED=TRUE。如果交付是最终调用并且不需要再向客户端返回另外的结果,那么事务结果即被确定为USER_CALL_COMPLETED=TRUE。
针对LTXID使用GET_LTXID_OUTCOME的输出
利用LTXID阻止命令集的完成
在一种示例性方法中,服务器在第二会话中从客户端接收识别由客户端在第一会话中利用LTXID发送的命令集作为身份验证的请求。一条或多条命令的集合如果在第一会话中完成就促使执行启动事务的第一服务器操作和交付事务的第二服务器操作。在本示例中,服务器确定命令集内是否还有至少一项已交付的事务。响应于请求和至少部分地基于确定命令集中没有已交付事务,服务器阻止第一会话中发送的命令集的完成。在一种使用情况下,除了阻止第一会话中发送命令集的完成以外,服务器还促使在第二会话中完成命令集。
图11示出了用于强制执行命令集的示例性方法。在步骤1101,客户端在身份验证、校验和更新LTXID时通过为客户端提供新LTXID的成功交付操作接收逻辑事务ID(LTXID)。客户端存留要在服务器使用的下一个LTXID。服务器会话存留并控制这一个相同的LTXID。在步骤1102,第一服务器从客户端接收用于在第一会话中执行的事务性命令集。在步骤1104,客户端未接收到事务性命令集已完成的报告。例如,客户端在发送命令集以供执行后的特定时间段以后可能无法接收报告。作为另一个示例,客户端可以接收第一会话已变为不可用的通知-客户端接收报错以指示发生了可恢复的故障。这些故障的示例有存储器、节点、服务器、网络或计划内关机。在步骤1106,服务器利用来自初始会话的LTXID从客户端接收识别事务性命令集的请求作为身份验证。在步骤1008,第二服务器确定事务性命令集中是否还有至少一项事务尚未交付。如果命令集中的所有事务均已交付,那么第二服务器就在步骤1110向客户端发送响应以指示事务性命令集已完成。如果在交付之后还存在事务性命令或者仍有数据要随交付结果返回(但是尚未返回),命令集就应输出已嵌入且用户调用仍未完成。如果命令集中没有已交付的事务,那么第二服务器就在步骤1112例如通过阻止事务历史中的LTXID而阻止第一会话中事务性命令集的完成。一旦事务性命令集在第一会话中被阻止,第二服务器就可以选择向用户返回未交付的结果。在一个实施例中,第二会话在步骤1114执行事务性命令集以完成第二会话,由此使得客户端可以在步骤1110接收事务性命令集可作为完成处理的指示。在一个可选实施例中,在步骤1116,第二服务器可以仅向客户端指明命令集已被阻止,并且客户端可以随后选择是否要重新运行命令。
在一个实施例中,数据库系统实现从应用程序的角度恢复工作并且为用户屏蔽大多数系统、通信和硬件故障。阻止机构禁止多于一次地执行终端用户的事务。在某些情况下,终端用户在由于不可恢复的错误例如逻辑故障或外界时间准则而停机时仍然可以看到服务的中断。
在一个实施例中,应用程序和数据源用集成的方式操作以使得如果任何组件故障或变为不响应则相关组件的事务性和非事务性状态均可恢复。在组件故障时,恢复程序将状态精确恢复为发生故障之前的状态。在请求因等待答复而超时并重新提交时,利用LTXID检测原始事务并且如果事务尚未交付新的会话就阻止原始事务禁止执行。为了支持最多一次的执行语义,如果有语句未交付则组件可以识别并允许重新运行。
在一个实施例中,对于应用程序,可恢复的错误是由于跟执行的应用程序会话逻辑无关的外部系统故障而产生的一类错误。可恢复的错误伴随网络、节点、存储器和数据库的计划内和意外停机而产生。例如,应用程序接收能够使应用程序无法获得提交的最终操作的输出的错误代码。应用程序可以跟服务器通信以重新建立数据库会话并重新提交用于这一类可恢复错误的相关工作。应用程序在由于不可恢复的错误造成的调用故障之后不能重新提交工作。不能触发自动重新运行的不可恢复错误的示例是如果命令重新运行就会生成跟命令在当前不可用的会话中本应生成的结果不同的数据值。
来自客户端的工作请求可以跨越多项数据库事务。例如,“结账”动作可以包括四项数据库事务:更新信用卡、更新库存、运送订单、将商品放入待发货列表。数据库事务是最简单级别的重试,并且数据库系统可以针对可恢复的错误重新建立用于数据库会话的对话状态并重复数据库会话。在一个实施例中,整个数据库会话如果还没有提交那就是可重复的。在一个实施例中,当客户端驱动程序检测到用户会话失败时,客户端驱动程序就请求新的用户会话。在一个示例中,针对拥有自身LTXID的新会话,客户端调用PL/SQL程序包中的GET_LTXID_OUTCOME给出失败用户会话的最新逻辑事务ID。如果该事务尚未交付,GET_LTXID_OUTCOME就采取动作将该LTXID交付至事务表。当LTXID已经不在其中时,这样做就具有阻止任何后续使用的效果。GET_LTXID_OUTCOME向客户端返回正常输出COMMITTED和USER_CALL_COMPLETED。如果LTXID在序列以外,GET_LTXID_OUTCOME也会报告错误以指示服务器超前(SERVER_AHEAD)或客户端超前(CLIENT_AHEAD)。一旦应用程序接收到最终事务的输出,应用程序就能够继续有所动作例如在当前会话中用属于该会话的LTXID重新运行或者不这样做。
在一个实施例中,客户端获取新会话并在会话句柄上设定失败用户会话的最终逻辑事务ID。当在服务器内处理连接请求并且会话句柄引用逻辑事务ID时,这就触发了GET_LTXID_OUTCOME函数的调用以获取跟该LTXID相关联的事务状态。连接请求在会话句柄中向用户返回事务的输出。根据最终事务的输出,最终事务能够重新运行或者因为事务已经交付或者能够向应用程序返回结果而不必重新运行。
在一个实施例中,客户端不得测试事务输出所用的事务表。访问事务表可以提供瞬间输出,但是瞬间输出可以随着事务继续向数据库交付而改变。瞬间输出如果被查询可以在输出到达客户端的时候变为过时。因此,对输出的请求可以跟阻止机制相集成以避免报告的输出变成过时。阻止机制在已向客户端报告事务输出之后阻止事务变成COMMITTED。事务可以随后在新的会话中自动交付或者在客户端请求时用新的会话交付。
检测服务器和客户端的不同步
在另一种示例性方法中,服务器从客户端接收请求以识别由客户端在会话中利用LTXID发送的特定命令集。请求识别LTXID但是并不识别会话接收的多个命令集中的最新命令集。最新命令集如果在会话中完成就会促使执行启动事务的第一服务器操作和交付事务的第二服务器操作。在本示例中,服务器确定请求无法识别会话接收的多个命令集中的最新命令集。响应于确定LTXID无法识别会话接收的多个命令集中的最新命令集,服务器向客户端发送对请求的响应以指示客户端跟服务器不同步。
在各种示例中,服务器可以确定服务器超前于客户端、客户端超前于服务器或者不管是客户端超前还是服务器超前都确定服务器和客户端不同步。在使用LTXID内交付序列的一个示例中,服务器确定特定的命令集是在最新命令集之前交付,并且从服务器到客户端的响应进一步指明服务器超前于客户端。在进一步的响应指明服务器超前于客户端的示例中,服务器利用LTXID内的交付序列确定特定命令集中的第一标识符在最新命令集中的第二标识符之前。
在使用LTXID内交付序列的另一个示例中,服务器确定特定命令集不在会话所接收的多个命令集内。服务器可以确定或者也可以不确定特定的命令集是在会话所接收的最早记录的命令集之前还是在会话所接收的最后记录的命令集之后。在使用LTXID内交付序列的另一个示例中,服务器确定特定命令集中的第一标识符在最新命令集中的第二标识符之后,并且响应进一步指明客户端超前于服务器。
在一个实施例中,服务器在一次会话中接收来自客户端的非同步请求,并且非同步请求引用由客户端在另一个不同的会话中发送的命令集。在这一个会话中,服务器向客户端发送响应以指明来自客户端的请求跟服务器不同步。
在一个实施例中,除了非同步的请求以外,服务器还从客户端接收另一种请求以在会话接收的多项事务中识别最新的事务。在本实施例中,服务器确定命令集内是否还有任何已交付的事务。至少部分地基于确定命令集内至少有一项事务已交付,服务器向客户端发送对另一种请求的另一种响应以指示命令集内至少有一项事务已交付以及在交付之后是否还有工作要完成或还有数据要返回也就是用户调用是否完成。在一个特定的示例中,请求引用第一会话中的命令集,并且服务器在第二会话中接收来自客户端的请求并做出响应。
在一个实施例中,除了引用第一会话中命令集的非同步请求以外,服务器还在第二会话中从客户端接收第二请求以在第一会话接收的多个命令集中识别最新的命令集。在本示例中,服务器确定命令集内是否不存在已交付的事务。响应于确定命令集内不存在已交付的事务,服务器阻止在第一会话中发送的一条或多条命令的集合的完成。在一个特定的示例中,服务器还在第二会话中促使完成命令集。
在一个实施例中,除了非同步的请求以外,服务器还从客户端接收第二请求以在会话接收的多个命令集中识别最新的命令集。在本示例中,服务器确定命令集内是否还有任何已交付的事务。至少部分地基于确定命令集内还有已交付的事务并且在交付之后没有要完成的工作或要返回的数据,服务器向客户端发送对请求的响应以指示用户调用可以作为已交付和已完成来处理。
图12示出了用于检查客户端是否跟服务器同步的示例性方法。在步骤1201,客户端首先在身份验证或者在从池中校验时从服务器接收并存留LTXID。在步骤1202,第一服务器从客户端接收用于在会话中执行的最新命令集。在步骤1204,客户端未接收到最新命令集已完成的报告。在步骤1206,第二服务器利用输送至客户端的LTXID从客户端接收识别第二命令集的请求。在步骤1208,第二服务器通过利用该LTXID确定在请求中识别的第二命令集是不是最新的命令集。如果答案为否,那么第二服务器就在步骤1210向客户端发送响应以指示客户端和服务器不同步。如果请求识别出最新的命令集,那么第二服务器就在步骤1212针对最新命令集执行后续处理。例如,第二服务器可以执行图10和图11中的步骤1012,1112和/或1114。
示例性的客户端一方的特征
在一个示例中,当驱动程序代理服务器或WebLogic服务器或第三方会话失败时,客户端首先利用客户端驱动程序提供的API-用于JDBC的getLTXID以及用于OCI的OCI_ATTR_GET和LTXID从先前失败的会话中获取LTXID。然后客户端通过该会话自身的逻辑事务ID获得新的会话。客户端调用GET_LTXID_OUTCOME函数,其中LTXID取自API。如果LTXID尚未被使用或者是上一次使用的LTXID加一,那就将失败会话中的原始LTXID标记为阻止。返回状态告知驱动程序最终事务未交付。丢失的事务可以用新的逻辑事务ID(跟新创建的会话相关联的LTXID)重新运行。如果该重新运行自身遭遇停机,那么重新运行的会话所用的LTXID即在另一个会话中被用于GET_LTXID_OUTCOME函数以确定输出。
在一个示例中,为了通过WebLogic服务器、客户端驱动程序或者由于重复请求提交而重新运行,客户端驱动程序或WebLogic服务器利用JDBC中的getLTXID以及OCI中的OCI_ATTR_GET和LTXID来访问由客户端驱动程序存留的最终LTXID。
JDBC驱动器提供在接收自服务器的每一个交付编号改变时执行的回调。WebLogic服务器利用该回调记录WebLogic服务器cookie中的LTXID。该cookie可以在WebLogic服务器集群上复制以有助于通过任何Java虚拟机(“JVM”)恢复请求的输出。通过很多浏览器窗口,用于WebLogic服务器的结构设置即可被设定为每个窗口一个cookie以使得能够检测到重复的提交。
下表提供了利用幂等性特征完成其自身重复运行的客户端或容器的示例。在表中,LTXID之后的编号是示例性的交付编号。
在一个实施例中,如果故障级联而无法完成,应用程序就将有效的LAST LTXID输送至FORCE_OUTCOME。下表提供了用于调用GET_LTXID_OUTCOME的示例性工作流以及因此报告的对不同状态的响应。
在一个实施例中,如果故障级联而无法完成,重新运行驱动程序就将有效的LASTLTXID输送至FPREPARE_REPLAY。如果确定事务可以生效,那么PREPARE_REPLAY就调用GET_LTXID_OUTCOME。下表提供了用于重新运行驱动程序的工作流。
在一个实施例中,LTXID仅在使用支持LTXID的客户端时创建。示例性的支持LTXID的客户端可以包括但不限于OCI客户端、JDBC瘦客户端和JDBC OCI客户端。支持LTXID的功能在ORACLE驱动程序-JDBC Thin、JDBC OCI和OCI以及位于OCI上层的包括ODP.NET和OCCI的接口上公用。
在一个实施例中,如果有事务开始或者如果当前有事务开启,那么客户端就使用会话句柄中的LTXID,所述LTXID跟事务一起在交付时记录。
在一个实施例中,在交付之后由服务器递加LTXID内的交付编号,然后通过交付消息将递加的LTXID返回给客户端驱动程序。在会话进行时,返回的LTXID被用于提交的下一项事务并且随后在每一次交付时递加。这种循环随着LTXID在每一次成功交付后递增而继续。
在一个实施例中,JDBC驱动器提供在接收自服务器的每一个交付编号改变时执行的回调。WebLogic服务器利用该回调记录WebLogic服务器cookie中的LTXID。该cookie可以在WebLogic服务器集群上复制以有助于通过任何JVM恢复请求的输出。通过很多浏览器窗口,用于WebLogic服务器的结构设置即可被设定为每个窗口一个cookie。
在一个实施例中,客户端接收FAN向下中断或错误。客户端放弃无效的会话。如果错误是可恢复的,客户端就校验新的会话。客户端利用GETLTXID或者从上下文区域获取最新的LTXID。客户端通过利用GETLTXID获得的最新LTXID调用GET_LTXID_OUTCOME。如果事务在进行交付,那么客户端就接收返回的结果。如果未进行交付,那么客户端可以将任何应用程序的状态改变退回重来并重新提交请求或向用户返回结果。如果交付出现并且用户调用尚未完成,那么应用程序可以将该信息返回给用户但是不应重新运行。
在一个实施例中,LTXID在连接校验时以及在每一次改变(也就是每一次成功交付)时被复制到http会话状态中。在每一次LTXID改变时,来自JDBC驱动程序的回调将LTXID的副本从客户端句柄输送至http会话状态(cookie)。如果WebLogic服务器实例失败,那么另一个WebLogic服务器能够恢复http会话状态并测试针对WebLogic服务器提交的最新输出。如果数据库实例(或服务器)故障,那么WebLogic服务器就能使用LTXID来测试提交的输出。
在一个实施例中,在校验时清除会话cookie中存留的LTXID。清除的数值在已完成的请求以外不可用。在另一个实施例中,每一个http会话都有其自身的在校验时存留的LTXID。
在一个实施例中,JDBC驱动程序使用称为ReplaydataSource的新数据源性质。该数据源可以是单池数据源以允许驱动程序在故障之后重新连接不同的数据库实例。在一个实施例中,数据源支持FAN/Fast连接故障切换和运行时负载平衡以用于快速故障检测和智能工作负荷分配至已知的好位置。
示例性连接池的特征
在一个实施例中,LTXID被存储为跟预先建立的连接和会话相关联并且在连接池内共享。在一个实施例中,LTXID存在于服务器和客户端的会话句柄中。LTXID在从连接池校验时跟应用程序请求关联,并且在登记返回池中时跟应用程序请求解除关联。在校验和登记之间,会话中的LTXID通过该应用程序请求排他性地存留。在登记之后,LTXID属于空闲的池中会话。LTXID跟校验该连接的下一个应用程序请求相关联。
在本实施例中,连接池可以支持针对当前http请求的重复检测和故障切换、基本WebLogic服务器对一项请求的中心运行以及WebLogic服务器重复运行并在WebLogic服务器或其他容器上进行复制以利用http会话状态保护中间层故障。
在另一个实施例中,LTXID在从任何中间层连接池第一次校验时被分配给用户请求,并且LTXID在随后的每一次校验请求时由web对话使用。LTXID序列不被其他的会话共享。在本实施例中,浏览器会话是跨边界的请求。根据交付给数据库的http会话来追踪请求。本实施例可以支持针对当前http请求的重复检测和故障切换,并且可以支持WebLogic服务器重复运行以及在WebLogic服务器或其他容器上进行复制以利用http会话状态保护中间层故障。即使受到挫折的用户在通过另一次请求完成事务之后再提交完成事务的请求,本实施例也可以唯一地识别会话。
在一个实施例中,当针对具有commit_outcome属性设置的服务建立连接并且在池内预先认证时,LTXID被存留在服务器和客户端的会话中。如果commit_outcome属性随后改变开/关状态,现有连接也保持其建立时的状态。数据库管理员(“DBA”)可以通过池的再利用来改变池的输出。
在很多示例中,数据库会话在HTTP请求首次连接到连接池时并未建立。相反,连接池可以从池中分配现有连接以满足校验请求。在校验时,由该数据库会话拥有的LTXID通过校验连接而跟http会话关联。
在登记时将连接返回连接池。由该数据库会话拥有的LTXID由http会话通过检验送回池中的会话而释放。通过不同http请求进行的下一次校验可以使用该会话,并且在一个实施例中,http会话状态在登记时被销毁。
在一个实施例中,用于http会话的第一校验请求通过在用于http会话的http会话状态中没有LTXID来确定。在第一次登录时,连接池管理程序调用LTXID读取函数以获得用于连接的起始逻辑事务ID。登录会设定LTXID,将LTXID送回客户端作为身份认证握手的一部分,并且将LTXID复制到客户端会话句柄中。随后的校验使用该相同的LTXID序列以避免往返行程。在一个实施例中,随后的校验请求跟来自先前对话的http会话上下文中设定的当前和下一个LTXID一起到达。对于输入的http请求和LTXID,WebLogic服务器事务管理程序(“TM”)询问WebLogic服务器池管理程序以在会话句柄中设定该LTXID。
在一个实施例中,当利用LTXID重新运行请求时,WebLogic服务器TM询问WebLogic服务器池管理程序以在会话句柄中设定该LTXID。WebLogic服务器TM随后调用GET_LTXID_OUTCOME。如果请求是COMMITTED或USER CALL未完成,那么WebLogic服务器TM就返回交付和完成的输出并退出。如果不是COMMITTED,那么WebLogic服务器就有重新提交请求的选择。
在另一个示例中,在http cookie上存留LTXID支持了不耐心用户的情况。用这种方式就能检测重复的再提交。只有使用LTXID的提交才能交付。
在登记时,句柄中的LTXID被复制到http会话状态中作为如果尚未完成时的下一个备用值。
在一个示例中,如果http会话超时,那么LTXID状态丢失并且在下一个校验请求时分配新的LTXID。为了支持http请求的重新运行,在WebLogic服务器和驱动程序中弃用http会话状态的超时应超过重新运行的超时。
相反地,如果LTXID存留时段小于WebLogic服务器,那么重新运行就由于LTXID超出序列而报错,或者如果是0交付层级就阻止。
在一个示例中,如果commit_outcome属性随后改变TRUE/FALSE取值,更早开始的http会话也保持其属性的初始值。
使用连接池时的LTXID管理
在另一种示例性方法中,连接管理程序针对多个可用数据库会话中的每一个存留连接对象,其中多个数据库服务器提供对数据库的访问。这些连接对象中的每一个都带有在身份验证时分配给该会话的LTXID。在本示例中,多个可用数据库会话中的每一个同时被分配给最多一个数据库服务器和最多一个客户端。用于每一个数据库会话的连接对象包括在多个数据库会话中唯一识别数据库会话的LTXID。连接管理程序从客户端接收对可用数据库会话的请求。响应于该请求,连接管理程序通过向客户端发送先前用过的可用数据库会话所用的连接对象而批准将先前用过的可用数据库会话至少部分地用于客户端。这样做的效果是批准将该连接对象上的LTXID用于应用程序。如果应用程序会话在往返行程中发出一项或多项事务,那这就是接下来要由服务器使用的LTXID。
在一个实施例中,为了区分下一个事务性命令集和已在先前用过的可用数据库会话中完成的多个事务性命令集,连接管理程序使用在先前用过的可用数据库会话中完成的逻辑事务标识符。连接对象存留在身份验证时以及在验证每一条交付消息之后接收的最新LTXID。这就一直是要由服务器使用的下一个LTXID。
在一个实施例中,响应于针对可用连接的请求,连接管理程序批准将先前用过的可用数据库会话用于具有分配LTXID效果的客户端。连接池管理程序还可以从客户端接收另外的请求以返回使用过的连接。响应于另外的请求,连接池管理程序释放由应用程序准备好用于下一次校验请求的LTXID。
图13示出了用于管理连接对象的示例性方法,所述连接对象包括会话识别信息以及用于在标识的会话内识别事务性命令集的信息。在步骤1302,连接管理程序存留供可用数据库会话使用的连接对象,其中数据库服务器提供对数据库的访问。在本示例中,每一个连接对象在识别出的会话中都包括LTXID。针对会话和存留交付输出的服务都有LTXID。无论事务是否已执行,客户端都存留下一个要使用的LTXID以使得只要有出现事务的可能就能够确定事务的输出。LTXID是服务器计划用于该会话的下一个取值,并且通过每一次交付更新和在交付时返回给客户端。如果客户端需要获知事务输出,那么客户端就将LTXID发送至服务器。
连接管理程序在步骤1304接收供可用数据库会话使用的请求。例如,请求可以从准备执行数据库会话中命令的客户端接收。在步骤1306,连接管理程序通过将供先前用过的可用数据库会话使用的连接对象分配给客户端来向客户端授权先前用过的可用数据库会话。在本示例中,连接对象包括先前用过的可用数据库会话中的LTXID。连接池管理程序也可以授权从未用过或者从未用于执行先前事务的新的数据库会话。在任何情况下,只要在往返行程中有事务发布,客户端就接收要使用的LTXID。
在一个实施例中,如步骤1308所示,连接池管理程序通过存储跟连接对象相关联的客户端专用信息例如通过存储对连接对象内客户端专用信息的索引来为客户端准备先前用过的可用数据库会话。步骤1308可以是向客户端授权先前用过的可用数据库会话的过程的一部分。例如,存储的应用程序背景、用户背景或安全背景在向客户端发送连接对象之前就可以跟连接对象相关联。在客户端已使用数据库会话或已经借用会话一段时间后,在步骤1310,连接管理程序可以从客户端接收请求以返回授权的数据库会话。响应于该请求,连接管理程序不做任何事,就像跟连接对象关联存储的客户端专用信息不存在一样。在另一个示例中,连接管理程序删除从连接对象到客户端专用信息的索引。在另一个示例中,连接管理程序删除自身的客户端专用信息。通常会话都被释放且不采取任何动作。
示例性的服务器一方的特征
在一个实施例中,用户通过数据库服务连接至数据库。服务的定义可以包括称为commit_outcome的属性。如果针对服务设有该属性,那就创建LTXID;否则就可以执行命令而无需跟踪事务。
在一个实施例中,服务器创建并存留逻辑事务ID。图2示出了用于管理数据库系统内的逻辑事务标识符(“LTXID”)的示例性步骤。如图所示,在步骤214,应用程序在新的数据库会话中通过对应的驱动程序连接至服务器。作为会话建立的一部分,服务器还创建新的LTXID。在一个示例中,LTXID仅创建并存储在内存中的用户会话结构内并随后返回给用户。此时,LTXID尚未存储在事务历史表中。新的LTXID在步骤218返回给驱动程序,并且用户能够查询会话句柄以获得LTXID的值。在一个示例中,LTXID以交付编号零开始。LTXID只有在变化被交付至数据库时才能改变。如果仅仅读取,那么LTXID不会改变。这是例如用于有效数据防护和只读的情况,并且此时通过浏览和读取来进行决策。
在一个实施例中,应用程序/驱动程序拥有设定附加属性跟LTXID相关联的能力。例如,附加属性可以被设定用于LLR事务和XA事务,跟WebLogic服务器或其他容器相集成以使VM、机器名或参与端点已知。
在一个实施例中,用户在步骤236通过执行DML、DDL或“SELECT FOR UPDATE”语句开启新的数据库会话以做出第一改变(第一次非递归的重做生成)。当服务器在步骤240首次生成redo时,事务在步骤242注册交付前和交付后的回调。该过程以同样的方式适用于DDL和DML语句,只要DDL在事务已激活时尚未开始即可。
在一个实施例中,在步骤256交付执行时,交付前回调在步骤258被调用并且在步骤260插入或更新事务历史表中的记录。如果事务是用户会话中的第一事务,那么就将新纪录插入事务历史表。在一个示例中,第一事务之后执行的事务仅更新事务历史表内的对应记录。在另一个示例中,每一项事务都有其自身的记录。在交付时更新或插入事务历史表被坚持作为跟客户端会话相同的数据库会话的一部分。交付前回调掠过自主事务和递归事务。
在一个实施例中,新的交付编号恰好是事务历史表中存储的新交付编号加一(事务历史表严格单调增加)。由于使用了GET_LTXID_OUTCOME,在故障切换时,新的工作通过LTXID继续,并且DBID和来自新实例的实例ID也是如此,所以无需再重设DBID或实例ID以保持划分。在一个实施例中,对于每一个用户会话,事务历史表中最多有一项记录。
在交付完成后调用交付后回调。交付后回调调用函数以获取下一个LTXID构成服务器要记录的下一个LTXID。在一个实施例中,函数并不创建新的LTXID,但是函数递加LTXID中的运行交付编号部分。新的LTXID在步骤264通过会话句柄返回给客户端以使客户端存留服务器计划使用的下一个LTXID。
在一个示例中,增量严格为一,建立单调增加的序列。在另一个示例中,LTXID以某种其他的可预测方式改变。如果该序列为乱序、具有间隙或者如果特定的LTXID不是预期的LTXID,那么重新运行就不可接受。在下一次交付时增加交付编号和更新LTXID是高度可量测的操作。
利用单调增加的交付编号可以保护以免针对丢失事务的数据库重新运行。在一个示例中,如果数据库已经通过以更早的具有数据保护的系统交付编号(“SCN”)、闪回或介质恢复打开而按时返回,那么只要在用于会话的交付序列中有间隙,该会话即可被禁止继续记录。
在一个示例中,客户端发送交付请求,并且事务被交付作为同一次交付的一部分。针对事务历史表的DML被交付作为该事务的一部分。首先执行交付前回调。LTXID交付记录被插入或更新以作为交付前回调的一部分。如果事务是用户会话中的第一事务,那就插入一行,并且后续事务在事务历史表的这一行内更新交付编号。更新而不是插入提供了更高的可量测性,不过其他的实施例也是可行的。
在事务已同步redo之后以及在返回交付消息之前,调用交付后回调。如果事务已被成功交付,那么逻辑事务ID的运行交付编号就在事务结束回调时递加并且返回SQL层。运行交付编号单调增加。新的逻辑事务ID被安静地返回给驱动程序作为交付消息所用返回结果的一部分。该会话的下一项事务就使用这个新的逻辑事务ID。
作为事务的一部分,DML语句和DDL语句均可执行。两种类型语句之间的一方面差异在于缺少自动交付模式,每一条DDL语句都在完成其工作后发出隐含的交付。另外,如果事务已经开启,那么就在执行DDL操作之前首先执行隐含交付。如果当前还没有开启事件,那么就以跟能够实现自动交付的DML操作相同的方式来处理DDL操作。
应用程序能够执行包含一项或多项交付操作的PL/SQL模块。对PL/SQL执行,没有记录的末端标记。如果在PL/SQL内执行交付,那么可能存在多种条件。这些条件包括嵌套的PL/SQL层级。在针对PL/SQL执行最新操作时可以是单次交付。在COMMIT之后可以有更多命令并且不再执行更多的COMMIT。在COMMIT之后可以有包括更多COMMIT的其他命令。在COMMIT之后可以有包括更多COMMIT且COMMIT是最终操作的其他命令。
命令集可以具有COMMITTED的输出,也就是说在COMMIT顶层调用结束时进行。这是跟顶层COMMIT相同的输出。可选地,命令集可以具有EMBEDDED的输出,也就是说COMMIT在顶层调用中进行并且在该COMMIT之后还可以有更多的工作或者还有数据要随着COMMIT的结果返回。在此情况下,“用户调用”具有已交付但是尚未完成的输出。对于GET_LTXID_OUTCOME函数,COMMITTED=TRUE,USER_CALL_COMPLETED=FALSE。
在一个实施例中,如果要在PL/SQL中执行一次或多次COMMIT,那么对于从客户端到服务器的往返行程,LTXID要递加多于一次。如果COMMIT是PL/SQL中的最终操作且没有能够潜在COMMIT的已注册调用,那么COMMIT的输出即被设定为FULL COMMIT(完全交付)。如果COMMIT不是PL/SQL中的最终操作或者没有能够潜在COMMIT的已注册调用,那么COMMIT的输出即被设定为EMBEDDED COMMIT(嵌入式交付)。一旦输出被设定为EMBEDDED,最终COMMIT操作的执行就将输出改变为COMMITTED。如果设定为完全交付,那么GET_LTXID_OUTCOME函数就返回COMMITTED=TRUE,USER_CALL_COMPLETED=TRUE。
在一个实施例中,通过在第一次redo生成时注册交付触发程序并记录COMMIT调用中的幂等性,自动交付事务即可得到完整保护。也就是说用于自动交付事务的输出能够通过使用LTXID获知。
在一个实施例,DDL在DDL开始和结束时执行隐含的顶层COMMIT。这就封装了DDL并建立起原子操作。COMMIT执行的编号和执行的层级都是DDL专用的。
在一个实施例中,如果尚未开启事务,那么初次交付是无操作(no-op)。如果有事务打开,那就注册交付前和交付后的触发程序,并且初次交付具有输出EMBEDDED。
在一个实施例中,DDL仅在最终的顶层COMMIT之后才递加LTXID。由于某些DDL在最终COMMIT时没有redo,因此执行交付前出发程序以明确地生成redo。用于DDL的COMMIT输出在DDL完成最终的顶层COMMIT之后是COMMITTED。如果输出被首次COMMIT设定为EMBEDDED,那么最终COMMIT具有更新为COMMITTED的输出。
在一个实施例中,PDML语句作为几项独立的从属事务而执行。并行度为N的PDML语句最多具有N+1项事务。PDML语句具有一项主事务和n项从属事务。主事务用作协调程序并插入或更新LTXID。如果任何一项从属事务失败,那个整项事务(包括所有从属事务)就退回重来且不插入LTXID。PDML内部使用两阶段交付协议以跨多个过程和数据库实例提供稳定的交付或退回。
图6示出了用于在执行并行输入操作语言(“PDML”)的语句时管理数据库系统内事务状态的示例性步骤。示例性步骤包括:
1.向服务器发送SQL语句(步骤614)
2.SQL层开启新事物(步骤618)
3.在第一次redo生成时,交付前和交付后的事务回调获得注册并且向事务层返回成功(步骤622)
4.建立或获取从属SQL并送往PL/SQL从属过程(步骤624)
5.将结果集合送回查询协调程序(步骤628)
6.向客户端返回结果(步骤630)
7.客户端过程发送交付命令(步骤632)
8.SQL层执行交付命令(步骤634)
9.TX层交付事务并调用交付前事务回调(步骤638)
10.交付后事务回调创建下一个逻辑事务ID(步骤642)
11.将新的逻辑事务ID和事务输出返回SQL层(步骤644)
12.将新的逻辑事务ID和事务输出通过交付消息返回客户端(步骤646)
在一个实施例中,在客户端于执行并行DML之前已开启本地事务的情况下,事务被隐含地转换为“并行”事务。不完成本地事务的隐含交付。
在一个实施例中,发布新的分布式事务的客户端用作分布式事务协调程序。在连接有客户端的数据库中,存储新的LTXID映射。在交付时,映射被插入事务历史表内。LTXID跟分布式事务相关联。分布式事务利用标准两阶段交付协议来交付或退回事务。
远程事务不同于目前讨论过的其他类型的数据库事务:它们能够在多于一个数据库内创建事务。
用于分布式事务的不同场景可以加以区分(包括1PC优化):
·两个或多个不同的数据库
·相同的RAC数据库实例
·相同的数据库实例
在启动远程事务时,可以在本地数据库建立“假”事务,并且在交付时,由于未在本地对数据库做出任何改变,因此不需要存留交付记录。交付的只有远程数据库中的事务。只要没有逻辑事务ID生成就可以保持这种行为。
在一个实施例中,对于远程事务,通常使用的假事务ID被映射至“真”事务,并且逻辑事务ID在生成首次redo时被存留在协调数据库的事务历史表内。这种改变将远程事务转化为分布式事务并且用跟分布式事务相同的方式处理。在一个实施例中,2PC协议被用于远程事务。
在远程数据库不需要逻辑事务ID,原因在于事务是通过分布式事务协调程序来交付或退回重来。分布式协调程序利用两阶段交付协议负责所有数据库实例的退回重来。
用于分布式事务的工作流非常类似于本地事务的情况。示例性步骤包括:
1.客户端向服务器发送SQL语句
2.SQL层接收新语句并开启新事务
3.在第一次redo生成时,注册交付前和交付后的事务回调。第一次redo可以是本地或远程的redo。向SQL层返回注册交付回调的成功。
4.SQL层向远程数据库发送SQL命令用于执行。LTXID不向其他的数据库发送;仅在用户连接的数据库内存留。
5.远程数据库向SQL层返回结果集合
6.向客户端返回结果集合/结果
7.客户端发出交付请求
8.交付请求被分析并送往事务层
9.事务层调用交付前回调并插入或更新事务历史表内的记录,然后交付事务自身并执行交付后回调。交付后回调创建下一个LTXID。
10.向事务层返回新的LTXID
11.向SQL层返回新的LTXID
12.随后将LTXID和交付消息一起返回客户端驱动程序
13.客户端驱动程序发起回调以使LTXID对更高层的容器可用
交付处理没有改变:分布式事务调用两阶段交付协议。事务在所有数据库或事务表内交付或退回重来。对逻辑事务ID的插入或更新作为同一项分布式事务的一部分而被存留。
在一个实施例中,附加的准备状态被加入事务状态表。该状态被称作IN_DOUBT(存疑)。如果事务处于准备状态,客户端不应在事务输出未知时重新提交事务。如果针对处于IN_DOUBT状态的事务调用GET_LTXID_OUTCOME,那么插入或更新LTXID的尝试就被阻止以在锁定状态等待。应用程序可以取消请求。
在一个实施例中,LTXID处理排除了自主事务。自主事务具有跟主事务不同的生命周期,并且自主事务没有与之关联的逻辑事务ID。自主事务可以被多于一次地执行。这就允许跟自主事务是否交付无关地重新运行无法交付的主对话。在本实施例中,针对自主事务不提供最多执行一次的语义。
单阶段交付(1PC)是对两阶段交付协议的优化。在一个实施例中,在发起交付(XA交付)之前,事务协调程序向所有事务分支发送准备消息,但是最多只有一个能够回复“PREPARED”。其他事务分支应回复“READ_ONLY”。在此情况下,交付仅向符合状态“PREPARED”的事务分支发送。由于DML不能在准备之后出现,因此选择一个LTXID用于记录。这就必须在准备执行之前进行记录。选择的LTXID被用于GET_LTXID_OUTCOME。在另一个实施例中,纪录的是GTRID而不是LTXID。由于GTRID对于所有分支都相同,因此客户端可以利用类似的函数GET_GTRID_OUTCOME查询GTRID以获知输出。在本实施例中由于GTRID已经跨越各个分支而不需要选择LTXID。
在一个实施例中,对于1PC优化,LTXID被记录并且仅在第一分支准备好后才递加。WebLogic服务器和其他容器获知哪一个分支最先准备好。WebLogic服务器利用LTXID和GET_LTXID_OUTCOME确定事务输出。在另一个实施例中,WebLogic服务器可以使用记录的GTRID确定事务的输出。
在一个实施例中,在客户端于停机后重新连接之后,客户端调用GET_LTXID_OUTCOME函数。如果过去的LTXID尚未交付,那GET_LTXID_OUTCOME函数就插入或更新跟先前会话相关联的LTXID。插入/更新将LTXID标记为阻止。应用程序随后即可通过新的LTXID(在建立会话时创建的LTXID)安全地重新运行事务或者向应用程序返回未交付的输出或者通过该输出采取某种其他的动作。
在一个实施例中,GET_LTXID_OUTCOME是可以公用的PL/SQL函数。在一个实施例中,内部FORCE_OUTCOME PL/SQL函数具有以下的输出:COMMITTED、EMBEDDED、FORCED和出错代码。FORCE_OUTCOME如果事务已交付就返回COMMITTED,如果交付已经在PL/SQL模块或存储java的过程中执行并且该COMMIT不是PL/SQL模块内的单次COMMIT和最终调用那就返回EMBEDDED,如果还有事务尚未交付或已经通过先前对FORCE_OUTCOME的调用放弃那就返回FORCED。公用的GET_LTXID_OUTCOME PL/SQL函数具有布尔型输出:COMMITTED和USER_CALL_COMPLETED以及出错代码。GET_LTXID__OUTCOME如果已交付任何事务那就返回COMMITTED=TRUE,如果交付已经在PL/SQL模块中执行并且该COMMIT不是PL/SQL模块内的单次COMMIT和最终调用或存储java的过程那就返回USER_CALL_COMPLETED=TRUE,还有如果事务尚未交付或已经通过先前对内部FORCE_OUTCOME的调用而放弃那就返回COMMITTED=FALSE。
在一个实施例中,如果事务在故障切换之后重新运行,那么就通过阻止的输出来记录原始的LTXID。如果原始会话尝试交付事务,那就检测并拒绝交付。阻止输出禁止交付带有相同LTXID的运行中事务,并且使应用程序能够根据最多执行一次的语义来安全地重新运行。新的LTXID(跟客户端重连/故障切换的会话相关联)被用于重新运行事务。
如果事务已经更新事务历史表内的记录并且记录行被锁定,那么GET_LTXID_OUTCOME函数就一直等待到先前事务完成。如果因为事务存疑而锁定行,那么FORCE_OUTCOME也要等待。
在一个实施例中,FORCE_OUTCOME的返回代码被映射至以下重新运行的操作:COMMITTED被映射至CONTINUE;FORCED被映射至REPLAY;EMBEDDED被映射至NO_REPLAY/ERROR;SERVER_AHEAD被映射至NO_REPLAY/ERROR;CLIENT_AHEAD被映射至NO_REPLAY/ERROR;并且OWN_SESSION被映射至NO_REPLAY/ERROR。
在零一个实施例中,GET_LTXID_OUTCOME的返回代码被映射至以下重新运行的操作:COMMITTED=TRUE和USER_CALL_COMPLETED=TRUE被映射至CONTINUE;COMMITTED=FALSE被映射至REPLAY;COMMITTED=TRUE和USER_CALL_COMPLETED=FALSE被映射至NO_REPLAY/ERROR;SERVER_AHEAD被映射至NO_REPLAY/ERROR;CLIENT_AHEAD被映射至NO_REPLAY/ERROR;并且OWN_SESSION被映射至NO_REPLAY/ERROR。
在一个实施例中,用户针对数据库执行DDL语句。DDL驱动程序隐含地交付每一条语句。最终的隐含交付将创建下一个LTXID并在同一个往返行程将新的LTXID送回客户端。单个DDL能够发起几次交付。在一个实施例中,对于这些交付中的每一次,LTXID的运行交付编号仅针对第一次增加。通过在每一个往返行程中增加交付编号不超过一次,如果客户端针对该LTXID测试事务输出则客户端就不会经历SERVER_AHEAD错误。
在一个实施例中,TRUNCATE DDL操作是幂等性的。TRUNCATE DDL操作作为一系列递归操作执行且并不注册用于或者递加LTXID。在一个实施例中,如果在运行TRUNCATE语句之前存在开启的事务,那么该事务就在舍位执行之前被隐含地交付。隐含交付加一地更新LTXID。否则LTXID就不通过TRUNCATE语句增加。在另一个实施例中,只要TRUNCATE操作完全截取任意的行LTXID就增加。
在一个实施例中,LTXID仅在使用支持LTXID的客户端时创建。示例性的支持LTXID的客户端可以包括但不限于OCI客户端、JDBC瘦客户端和JDBC OCI客户端。支持LTXID的功能在ORACLE驱动程序-JDBC Thin、JDBC OCI和OCI以及位于OCI上层的包括ODP.NET和OCCI的接口上公用。
在一个实施例中,如果有事务开始或者如果当前有事务开启,那么客户端就使用会话句柄中的LTXID,所述LTXID跟事务一起在交付时记录。
在一个实施例中,在交付之后由服务器递加LTXID内的交付编号,然后通过交付消息将递加的LTXID返回给客户端驱动程序。在会话进行时,返回的LTXID被用于提交的下一项事务并且随后在每一次交付时递加。这种循环随着LTXID在每一次成功交付后递增而继续。
在一个实施例中,JDBC驱动器提供在接收自服务器的每一个交付编号改变时执行的回调。WebLogic服务器利用该回调记录WebLogic服务器cookie中的LTXID。该cookie可以在WebLogic服务器集群上复制以有助于通过任何JVM恢复请求的输出。通过很多浏览器窗口,用于WebLogic服务器的结构设置即可被设定为每个窗口一个cookie。
在一个实施例中,客户端接收FAN向下中断或错误。客户端放弃无效的会话。如果错误是可恢复的,客户端就校验新的会话。客户端利用GETLTXID或者从上下文区域获取最新的LTXID。客户端通过利用GETLTXID获得的最新LTXID调用GET_LTXID_OUTCOME.如果事务在进行交付,那么客户端就接收返回的结果。如果未进行交付,那么客户端可以将任何应用程序的状态改变退回重来并重新提交请求或向用户返回结果。如果交付出现并且用户调用尚未完成,那么应用程序可以将该信息返回给用户但是不应重新运行。
在一个实施例中,LTXID在连接校验时以及在每一次改变(也就是每一次成功交付)时被复制到http会话状态中。在每一次LTXID改变时,来自JDBC驱动程序的回调将LTXID的副本从客户端句柄输送至http会话状态(cookie)。如果WebLogic服务器实例失败,那么另一个WebLogic服务器能够恢复http会话状态并测试针对WebLogic服务器提交的最新输出。如果数据库实例(或服务器)故障,那么WebLogic服务器就能使用LTXID来测试提交的输出。
在一个实施例中,在校验时清除会话cookie中存留的LTXID。清除的数值在已完成的请求以外不可用。在另一个实施例中,每一个http会话都有其自身的在校验时存留的LTXID。
在一个实施例中,JDBC驱动程序使用称为ReplaydataSource的新数据源性质。该数据源可以是单池数据源以允许驱动程序在故障之后重新连接不同的数据库实例。在一个实施例中,数据源支持FAN/Fast连接故障切换和运行时负载平衡以用于快速故障检测和智能工作负荷分配至已知的好位置。
示例性连接池的特征
在一个实施例中,LTXID被存储为跟预先建立的连接和会话相关联并且在连接池内共享。在一个实施例中,LTXID存在于服务器和客户端的会话句柄中。LTXID在从连接池校验时跟应用程序请求关联,并且在登记返回池中时跟应用程序请求解除关联。在校验和登记之间,会话中的LTXID通过该应用程序请求排他性地存留。在登记之后,LTXID属于空闲的池中会话。LTXID跟校验该连接的下一个应用程序请求相关联。
在本实施例中,连接池可以支持针对当前http请求的重复检测和故障切换、基本WebLogic服务器对一项请求的中心运行以及WebLogic服务器重复运行并在WebLogic服务器或其他容器上进行复制以利用http会话状态保护中间层故障。
在另一个实施例中,LTXID在从任何中间层连接池第一次校验时被分配给用户请求,并且LTXID在随后的每一次校验请求时由web对话使用。LTXID序列不被其他的会话共享。在本实施例中,浏览器会话是跨边界的请求。根据交付给数据库的http会话来追踪请求。本实施例可以支持针对当前http请求的重复检测和故障切换,并且可以支持WebLogic服务器重复运行以及在WebLogic服务器或其他容器上进行复制以利用http会话状态保护中间层故障。即使受到挫折的用户在通过另一次请求完成事务之后再提交完成事务的请求,本实施例也可以唯一地识别会话。
在一个实施例中,当针对具有commit_outcome属性设置的服务建立连接并且在池内预先认证时,LTXID被存留在服务器和客户端的会话中。如果commit_outcome属性随后改变开/关状态,现有连接也保持其建立时的状态。数据库管理程序(“DBA”)可以通过池的再利用来改变池的输出。
在很多示例中,数据库会话在HTTP请求首次连接到连接池时并未建立。相反,连接池可以从池中分配现有连接以满足校验请求。在校验时,由该数据库会话拥有的LTXID通过校验连接而跟http会话关联。
在登记时将连接返回连接池。由该数据库会话拥有的LTXID由http会话通过检验送回池中的会话而释放。通过不同http请求进行的下一次校验可以使用该会话,并且在一个实施例中,http会话状态在登记时被销毁。
在一个实施例中,用于http会话的第一校验请求通过在用于http会话的http会话状态中没有LTXID来确定。在第一次登录时,连接池管理程序调用LTXID读取函数以获得用于连接的起始逻辑事务ID。登录会设定LTXID,将LTXID送回客户端作为身份认证握手的一部分,并且将LTXID复制到客户端会话句柄中。随后的校验使用该相同的LTXID序列以避免往返行程。在一个实施例中,随后的校验请求跟来自先前对话的http会话上下文中设定的当前和下一个LTXID一起到达。对于输入的http请求和LTXID,WebLogic服务器事务管理程序(“TM”)询问WebLogic服务器池管理程序以在会话句柄中设定该LTXID。
在一个实施例中,当利用LTXID重新运行请求时,WebLogic服务器TM询问WebLogic服务器池管理程序以在会话句柄中设定该LTXID。WebLogic服务器TM随后调用GET_LTXID_OUTCOME。如果请求是COMMITTED或USER CALL未完成,那么WebLogic服务器TM就返回交付和完成的输出并退出。如果不是COMMITTED,那么WebLogic服务器就有重新提交请求的选择。
在另一个示例中,在http cookie上存留LTXID支持了不耐心用户的情况。用这种方式就能检测重复的再提交。只有使用LTXID的提交才能交付。
在登记时,句柄中的LTXID被复制到http会话状态中作为如果尚未完成时的下一个备用值。
在一个示例中,如果http会话超时,那么LTXID状态丢失并且在下一个校验请求时分配新的LTXID。为了支持http请求的重新运行,在WebLogic服务器和驱动程序中弃用http会话状态的超时应超过重新运行的超时。
相反地,如果LTXID存留时段小于WebLogic服务器,那么重新运行就由于LTXID超出序列而报错,或者如果是0交付层级就阻止。
在一个示例中,如果commit_outcome属性随后改变TRUE/FALSE取值,更早开始的http会话也保持其属性的初始值。
使用连接池时的LTXID管理
在另一种示例性方法中,连接管理程序针对多个可用数据库会话中的每一个存留连接对象,其中多个数据库服务器提供对数据库的访问。这些连接对象中的每一个都带有在身份验证时分配给该会话的LTXID。在本示例中,多个可用数据库会话中的每一个同时被分配给最多一个数据库服务器和最多一个客户端。用于每一个数据库会话的连接对象包括在多个数据库会话中唯一识别数据库会话的LTXID。连接管理程序从客户端接收对可用数据库会话的请求。响应于该请求,连接管理程序通过向客户端发送先前用过的可用数据库会话所用的连接对象而批准将先前用过的可用数据库会话至少部分地用于客户端。这样做的效果是批准将该连接对象上的LTXID用于应用程序。如果应用程序会话在往返行程中发出一项或多项事务,那这就是接下来要由服务器使用的LTXID。
在一个实施例中,为了区分下一个事务性命令集和已在先前用过的可用数据库会话中完成的多个事务性命令集,连接管理程序使用在先前用过的可用数据库会话中完成的逻辑事务标识符。连接对象存留在身份验证时以及在验证每一条交付消息之后接收的最新LTXID。这就一直是要由服务器使用的下一个LTXID。
在一个实施例中,响应于针对可用连接的请求,连接管理程序批准将先前用过的可用数据库会话用于具有分配LTXID效果的客户端。连接池管理程序还可以从客户端接收另外的请求以返回使用过的连接。响应于另外的请求,连接池管理程序释放由应用程序准备好用于下一次校验请求的LTXID。
图13示出了用于管理连接对象的示例性方法,所述连接对象包括会话识别信息以及用于在标识的会话内识别事务性命令集的信息。在步骤1302,连接管理程序存留供可用数据库会话使用的连接对象,其中数据库服务器提供对数据库的访问。在本示例中,每一个连接对象在识别出的会话中都包括LTXID。针对会话和存留交付输出的服务都有LTXID。无论事务是否已执行,客户端都存留下一个要使用的LTXID以使得只要有出现事务的可能就能够确定事务的输出。LTXID是服务器计划用于该会话的下一个取值,并且通过每一次交付更新和在交付时返回给客户端。如果客户端需要获知事务输出,那么客户端就将LTXID发送至服务器。
连接管理程序在步骤1304接收供可用数据库会话使用的请求。例如,请求可以从准备执行数据库会话中的命令的客户端接收。在步骤1306,连接管理程序通过将供先前用过的可用数据库会话使用的连接对象分配给客户端来向客户端授权先前用过的可用数据库会话。在本示例中,连接对象包括先前用过的可用数据库会话中的LTXID。连接池管理程序也可以授权从未用过或者从未用于执行先前事务的新的数据库会话。在任何情况下,只要在往返行程中有事务发布,客户端就接收要使用的LTXID。
在一个实施例中,如步骤1308所示,连接池管理程序通过存储跟连接对象相关联的客户端专用信息例如通过存储对连接对象内客户端专用信息的索引来为客户端准备先前用过的可用数据库会话。步骤1308可以是向客户端授权先前用过的可用数据库会话的过程的一部分。例如,存储的应用程序背景、用户背景或安全背景在向客户端发送连接对象之前就可以跟连接对象相关联。在客户端已使用数据库会话或已经借用会话一段时间后,在步骤1310,连接管理程序可以从客户端接收请求以返回授权的数据库会话。响应于该请求,连接管理程序不做任何事,就像跟连接对象关联存储的客户端专用信息不存在一样。在另一个示例中,连接管理程序删除从连接对象到客户端专用信息的索引。在另一个示例中,连接管理程序删除自身的客户端专用信息。通常会话都被释放且不采取任何动作。
示例性的服务器一方的特征
在一个实施例中,用户通过数据库服务连接至数据库。服务的定义可以包括称为commit_outcome的属性。如果针对服务设有该属性,那就创建LTXID;否则就可以执行命令而无需跟踪事务。
在一个实施例中,服务器创建并存留逻辑事务ID。图2示出了用于管理数据库系统内的逻辑事务标识符(“LTXID”)的示例性步骤。如图所示,在步骤214,应用程序在新的数据库会话中通过对应的驱动程序连接至服务器。作为会话建立的一部分,服务器还创建新的LTXID。在一个示例中,LTXID仅创建并存储在内存中的用户会话结构内并随后返回给用户。此时,LTXID尚未存储在事务历史表中。新的LTXID在步骤218返回给驱动程序,并且用户能够查询会话句柄以获得LTXID的值。在一个示例中,LTXID以交付编号零开始。LTXID只有在变化被交付至数据库时才能改变。如果仅仅读取,那么LTXID不会改变。这是例如用于有效数据保护和只读的情况,并且此时通过浏览和读取来进行决策。
在一个实施例中,应用程序/驱动程序拥有设定附加属性跟LTXID相关联的能力。例如,附加属性可以被设定用于LLR事务和XA事务,跟WebLogic服务器或其他容器相集成以使VM、机器名或参与端点已知。
在一个实施例中,用户在步骤236通过执行DML、DDL或“SELECT FOR UPDATE”语句开启新的数据库会话以做出第一改变(第一次非递归的重做生成)。当服务器在步骤240首次生成redo时,事务在步骤242注册交付前和交付后的回调。该过程以同样的方式适用于DDL和DML语句,只要DDL在事务已激活时尚未开始即可。
在一个实施例中,在步骤256交付执行时,交付前回调在步骤258被调用并且在步骤260插入或更新事务历史表中的记录。如果事务是用户会话中的第一事务,那么就将新纪录插入事务历史表。在一个示例中,第一事务之后执行的事务仅更新事务历史表内的对应记录。在另一个示例中,每一项事务都有其自身的记录。在交付时更新或插入事务历史表被坚持作为跟客户端会话相同的数据库会话的一部分。交付前回调掠过自主事务和递归事务。
在一个实施例中,新的交付编号恰好是事务历史表中存储的新交付编号加一(事务历史表严格单调增加)。由于使用了GET_LTXID_OUTCOME,在故障切换时,新的工作通过LTXID继续,并且DBID和来自新实例的实例ID也是如此,所以无需再重设DBID或实例ID以保持划分。在一个实施例中,对于每一个用户会话,事务历史表中最多有一项记录。
在交付完成后调用交付后回调。交付后回调调用函数以获取下一个LTXID构成服务器要记录的下一个LTXID。在一个实施例中,函数并不创建新的LTXID,但是函数递加LTXID中的运行交付编号部分。新的LTXID在步骤264通过会话句柄返回给客户端以使客户端存留服务器计划使用的下一个LTXID。
在一个示例中,增量严格为一,建立单调增加的序列。在另一个示例中,LTXID以某种其他的可预测方式改变。如果该序列为乱序、具有间隙或者如果特定的LTXID不是预期的LTXID,那么重新运行就不可接受。在下一次交付时增加交付编号和更新LTXID是高度可量测的操作。
利用单调增加的交付编号可以保护以免针对丢失事务的数据库重新运行。在一个示例中,如果数据库已经通过以更早的具有数据保护的系统交付编号(“SCN”)、闪回或介质恢复打开而按时返回,那么只要在用于会话的交付序列中有间隙,该会话即可被禁止继续记录。
在一个示例中,客户端发送交付请求,并且事务被交付作为同一次交付的一部分。针对事务历史表的DML被交付作为该事务的一部分。首先执行交付前回调。LTXID交付记录被插入或更新以作为交付前回调的一部分。如果事务是用户会话中的第一事务,那就插入一行,并且后续事务在事务历史表的这一行内更新交付编号。更新而不是插入提供了更高的可量测性,不过其他的实施例也是可行的。
在事务已同步redo之后以及在返回交付消息之前,调用交付后回调。如果事务已被成功交付,那么逻辑事务ID的运行交付编号就在事务结束回调时递加并且返回SQL层。运行交付编号单调增加。新的逻辑事务ID被安静地返回给驱动程序作为交付消息所用返回结果的一部分。该会话的下一项事务就使用这个新的逻辑事务ID。
作为事务的一部分,DML语句和DDL语句均可执行。两种类型语句之间的一方面差异在于缺少自动交付模式,每一条DDL语句都在完成其工作后发出隐含的交付。另外,如果事务已经开启,那么就在执行DDL操作之前首先执行隐含交付。如果当前还没有开启事件,那么就以跟能够实现自动交付的DML操作相同的方式来处理DDL操作。
应用程序能够执行包含一项或多项交付操作的PL/SQL模块。对PL/SQL执行,没有记录的末端标记。如果在PL/SQL内执行交付,那么可能存在多种条件。这些条件包括嵌套的PL/SQL层级。在针对PL/SQL执行最新操作时可以是单次交付。在COMMIT之后可以有更多命令并且不再执行更多的COMMIT。在COMMIT之后可以有包括更多COMMIT的其他命令。在COMMIT之后可以有包括更多COMMIT且COMMIT是最终操作的其他命令。
命令集可以具有COMMITTED的输出,也就是说在COMMIT顶层调用结束时进行。这是跟顶层COMMIT相同的输出。可选地,命令集可以具有EMBEDDED的输出,也就是说COMMIT在顶层调用中进行并且在该COMMIT之后还可以有更多的工作或者还有数据要随着COMMIT的结果返回。在此情况下,“用户调用”具有已交付但是尚未完成的输出。对于GET_LTXID_OUTCOME函数,COMMITTED=TRUE,USER_CALL_COMPLETED=FALSE。
在一个实施例中,如果要在PL/SQL中执行一次或多次COMMIT,那么对于从客户端到服务器的往返行程,LTXID要递加多于一次。如果COMMIT是PL/SQL中的最终操作且没有能够潜在COMMIT的已注册调用,那么COMMIT的输出即被设定为FULL COMMIT(完全交付)。如果COMMIT不是PL/SQL中的最终操作或者没有能够潜在COMMIT的已注册调用,那么COMMIT的输出即被设定为EMBEDDED COMMIT(嵌入式交付)。一旦输出被设定为EMBEDDED,最终COMMIT操作的执行就将输出改变为COMMITTED。如果设定为完全交付,那么GET_LTXID_OUTCOME函数就返回COMMITTED=TRUE,USER_CALL_COMPLETED=TRUE。
在一个实施例中,通过在第一次redo生成时注册交付触发程序并记录COMMIT调用中的幂等性,自动交付事务即可得到完整保护。也就是说用于自动交付事务的输出能够通过使用LTXID获知。
在一个实施例,DDL在DDL开始和结束时执行隐含的顶层COMMIT。这就封装了DDL并建立起原子操作。COMMIT执行的编号和执行的层级都是DDL专用的。
在一个实施例中,如果尚未开启事务,那么初次交付是无操作(no-op)。如果有事务打开,那就注册交付前和交付后的触发程序,并且初次交付具有输出EMBEDDED。
在一个实施例中,DDL仅在最终的顶层COMMIT之后才递加LTXID。由于某些DDL在最终COMMIT时没有redo,因此执行交付前触发程序以明确地生成redo。用于DDL的COMMIT输出在DDL完成最终的顶层COMMIT之后是COMMITTED。如果输出被首次COMMIT设定为EMBEDDED,那么最终COMMIT具有更新为COMMITTED的输出。
在一个实施例中,PDML语句作为几项独立的从属事务而执行。并行度为N的PDML语句最多具有N+1项事务。PDML语句具有一项主事务和n项从属事务。主事务用作协调程序并插入或更新LTXID。如果任何一项从属事务失败,那个整项事务(包括所有从属事务)就退回重来且不插入LTXID。PDML内部使用两阶段交付协议以跨多个过程和数据库实例提供稳定的交付或退回。
图6示出了用于在执行并行输入操作语言(“PDML”)的语句时管理数据库系统内事务状态的示例性步骤。示例性步骤包括:
1.向服务器发送SQL语句(步骤614)
2.SQL层开启新事物(步骤618)
3.在第一次redo生成时,交付前和交付后的事务回调获得注册并且向事务层返回成功(步骤622)
4.建立或获取从属SQL并送往PL/SQL从属过程(步骤624)
5.将结果集合送回查询协调程序(步骤628)
6.向客户端返回结果(步骤630)
7.客户端过程发送交付命令(步骤632)
8.SQL层执行交付命令(步骤634)
9.TX层交付事务并调用交付前事务回调(步骤638)
10.交付后事务回调创建下一个逻辑事务ID(步骤642)
11.将新的逻辑事务ID和事务输出返回SQL层(步骤644)
12.将新的逻辑事务ID和事务输出通过交付消息返回客户端(步骤646)
在一个实施例中,在客户端于执行并行DML之前已开启本地事务的情况下,事务被隐含地转换为“并行”事务。不完成本地事务的隐含交付。
在一个实施例中,发布新的分布式事务的客户端用作分布式事务协调程序。在连接有客户端的数据库中,存储新的LTXID映射。在交付时,映射被插入事务历史表内。LTXID跟分布式事务相关联。分布式事务利用标准两阶段交付协议来交付或退回事务。
远程事务不同于目前讨论过的其他类型的数据库事务:它们能够在多于一个数据库内创建事务。
用于分布式事务的不同场景可以加以区分(包括1PC优化):
·两个或多个不同的数据库
·相同的RAC数据库实例
·相同的数据库实例
在启动远程事务时,可以在本地数据库建立“假”事务,并且在交付时,由于未在本地对数据库做出任何改变,因此不需要存留交付记录。交付的只有远程数据库中的事务。只要没有逻辑事务ID生成就可以保持这种行为。
在一个实施例中,对于远程事务,通常使用的假事务ID被映射至“真”事务,并且逻辑事务ID在生成首次redo时被存留在协调数据库的事务历史表内。这种改变将远程事务转化为分布式事务并且用跟分布式事务相同的方式处理。在一个实施例中,2PC协议被用于远程事务。
在远程数据库不需要逻辑事务ID,原因在于事务是通过分布式事务协调程序来交付或退回重来。分布式协调程序利用两阶段交付协议负责所有数据库实例的退回重来。
用于分布式事务的工作流非常类似于本地事务的情况。示例性步骤包括:
1.客户端向服务器发送SQL语句
2.SQL层接收新语句并开启新事务
3.在第一次redo生成时,注册交付前和交付后的事务回调。第一次redo可以是本地或远程的redo。向SQL层返回注册交付回调的成功。
4.SQL层向远程数据库发送SQL命令用于执行。LTXID不向其他的数据库发送;仅在用户连接的数据库内存留。
5.远程数据库向SQL层返回结果集合
6.向客户端返回结果集合/结果
7.客户端发出交付请求
8.交付请求被分析并送往事务层
9.事务层调用交付前回调并插入或更新事务历史表内的记录,然后交付事务自身并执行交付后回调。交付后回调创建下一个LTXID。
10.向事务层返回新的LTXID
11.向SQL层返回新的LTXID
12.随后将LTXID和交付消息一起返回客户端驱动程序
13.客户端驱动程序发起回调以使LTXID对更高层的容器可用
交付处理没有改变:分布式事务调用两阶段交付协议。事务在所有数据库或事务表内交付或退回重来。对逻辑事务ID的插入或更新作为同一项分布式事务的一部分而被存留。
在一个实施例中,附加的准备状态被加入事务状态表。该状态被称作IN_DOUBT(存疑)。如果事务处于准备状态,客户端不应在事务输出未知时重新提交事务。如果针对处于IN_DOUBT状态的事务调用GET_LTXID_OUTCOME,那么插入或更新LTXID的尝试就被阻止以在锁定状态等待。应用程序可以取消请求。
在一个实施例中,LTXID处理排除了自主事务。自主事务具有跟主事务不同的生命周期,并且自主事务没有与之关联的逻辑事务ID。自主事务可以被多于一次地执行。这就允许跟自主事务是否交付无关地重新运行无法交付的主对话。在本实施例中,针对自主事务不提供最多执行一次的语义。
单阶段交付(1PC)是对两阶段交付协议的优化。在一个实施例中,在发起交付(XA交付)之前,事务协调程序向所有事务分支发送准备消息,但是最多只有一个能够回复“PREPARED”。其他事务分支应回复“READ_ONLY”。在此情况下,交付仅向符合状态“PREPARED”的事务分支发送。由于DML不能在准备之后出现,因此选择一个LTXID用于记录。这就必须在准备执行之前进行记录。选择的LTXID被用于GET_LTXID_OUTCOME。在另一个实施例中,纪录的是GTRID而不是LTXID。由于GTRID对于所有分支都相同,因此客户端可以利用类似的函数GET_GTRID_OUTCOME查询GTRID以获知输出。在本实施例中由于GTRID已经跨越各个分支而不需要选择LTXID。
在一个实施例中,对于1PC优化,LTXID被记录并且仅在第一分支准备好后才递加。WebLogic服务器和其他容器获知哪一个分支最先准备好。WebLogic服务器利用LTXID和GET_LTXID_OUTCOME确定事务输出。在另一个实施例中,WebLogic服务器可以使用记录的GTRID确定事务的输出。
在一个实施例中,在客户端于停机后重新连接之后,客户端调用GET_LTXID_OUTCOME函数。如果过去的LTXID尚未交付,那GET_LTXID_OUTCOME函数就插入或更新跟先前会话相关联的LTXID。插入/更新将LTXID标记为阻止。应用程序随后即可通过新的LTXID(在建立会话时创建的LTXID)安全地重新运行事务或者向应用程序返回未交付的输出或者通过该输出采取某种其他的动作。
在一个实施例中,GET_LTXID_OUTCOME是可以公用的PL/SQL函数。在一个实施例中,内部FORCE_OUTCOME PL/SQL函数具有以下的输出:COMMITTED、EMBEDDED、FORCED和出错代码。FORCE_OUTCOME如果事务已交付就返回COMMITTED,如果交付已经在PL/SQL模块或存储java的过程中执行并且该COMMIT不是PL/SQL模块内的单次COMMIT和最终调用那就返回EMBEDDED,如果还有事务尚未交付或已经通过先前对FORCE_OUTCOME的调用放弃那就返回FORCED。公用的GET_LTXID_OUTCOME PL/SQL函数具有布尔型输出:COMMITTED和USER_CALL_COMPLETED以及出错代码。GET_LTXID__OUTCOME如果已交付任何事务那就返回COMMITTED=TRUE,如果交付已经在PL/SQL模块中执行并且该COMMIT不是PL/SQL模块内的单次COMMIT和最终调用或存储java的过程那就返回USER_CALL_COMPLETED=TRUE,还有如果事务尚未交付或已经通过先前对内部FORCE_OUTCOME的调用而放弃那就返回COMMITTED=FALSE。
在一个实施例中,如果事务在故障切换之后重新运行,那么就通过阻止的输出来记录原始的LTXID。如果原始会话尝试交付事务,那就检测并拒绝交付。阻止输出禁止交付带有相同LTXID的运行中事务,并且使应用程序能够根据最多执行一次的语义来安全地重新运行。新的LTXID(跟客户端重连/故障切换的会话相关联)被用于重新运行事务。
如果事务已经更新事务历史表内的记录并且记录行被锁定,那么GET_LTXID_OUTCOME函数就一直等待到先前事务完成。如果因为事务存疑而锁定行,那么FORCE_OUTCOME也要等待。
在一个实施例中,FORCE_OUTCOME的返回代码被映射至以下重新运行的操作:COMMITTED被映射至CONTINUE;FORCED被映射至REPLAY;EMBEDDED被映射至NO_REPLAY/ERROR;SERVER_AHEAD被映射至NO_REPLAY/ERROR;CLIENT_AHEAD被映射至NO_REPLAY/ERROR;并且OWN_SESSION被映射至NO_REPLAY/ERROR。
在另一个实施例中,GET_LTXID_OUTCOME的返回代码被映射至以下重新运行的操作:COMMITTED=TRUE和USER_CALL_COMPLETED=TRUE被映射至CONTINUE;COMMITTED=FALSE被映射至REPLAY;COMMITTED=TRUE和USER_CALL_COMPLETED=FALSE被映射至NO_REPLAY/ERROR;SERVER_AHEAD被映射至NO_REPLAY/ERROR;CLIENT_AHEAD被映射至NO_REPLAY/ERROR;并且OWN_SESSION被映射至NO_REPLAY/ERROR。
在一个实施例中,用户针对数据库执行DDL语句。DDL驱动程序隐含地交付每一条语句。最终的隐含交付将创建下一个LTXID并在同一个往返行程将新的LTXID送回客户端。单个DDL能够发起几次交付。在一个实施例中,对于这些交付中的每一次,LTXID的运行交付编号仅针对第一次增加。通过在每一个往返行程中增加交付编号不超过一次,如果客户端针对该LTXID测试事务输出则客户端就不会经历SERVER_AHEAD错误。
在一个实施例中,TRUNCATE DDL操作是幂等性的。TRUNCATE DDL操作作为一系列递归操作执行且并不注册用于或者递加LTXID。在一个实施例中,如果在运行TRUNCATE语句之前存在开启的事务,那么该事务就在舍位执行之前被隐含地交付。隐含交付加一地更新LTXID。否则LTXID就不通过TRUNCATE语句增加。在另一个实施例中,只要TRUNCATE操作完全截取任意的行LTXID就增加。
在一个实施例中,客户端发出DDL命令并开启事务。如果应用程序在其发出DDL语句时已经将事务开启,那么开启的事务就被隐含地交付;LTXID在此超前。在DDL执行时,这就促使LTXID再次递加。为此,来自客户端的每一次往返行程都将LTXID增加不超过一,这跟该往返行程中执行多少次交付操作无关。
在一个实施例中,如果确实出现了多次COMMIT,那么FORCE_OUTCOME PL/SQL调用就由于客户端句柄上的LTXID超前于服务器多于一而返回错误值SERVER_AHEAD。客户端应该认为由于DDL可能还有更多工作要做,因此重新运行不安全。如上所述,在主要的实施例中,为此来自客户端的每一次往返行程都将LTXID增加不超过一,这跟该往返行程中执行多少次交付操作无关。
在一个实施例中,在交付时更新或插入事务历史表被坚持作为跟客户端会话相同的数据库会话的一部分。在交付完成后调用交付后回调。交付后回调调用函数以获取下一个逻辑事务ID。在一个示例中,函数并不创建新的LTXID。函数递加逻辑事务ID中的运行交付编号部分。新的逻辑事务ID通过会话句柄返回给客户端。这是一种高度可量测的设计,原因就在于更新是就地执行。
在一种使用情况下,重新运行是针对具有其自身LTXID的会话。如果事务是在故障切换之后重新运行,那么获取下一个LTXID并作为事务结束回调的一部分执行的函数不仅更新交付编号,而且还更新实例ID值以准确地指定将要执行下一项事务的实例。
在一个实施例中,COMMIT命令的NOWAIT选项并未集成commit_outcome服务。如果跟“commit_outcome”服务相连的用户会话执行COMMIT NOWAIT命令,交付即被发出,并且不保证交付被存留。如果服务器故障,那么只要LTXID在客户端超前并接收但是交付不存留FORCE_OUTCOME就可以返回错误值CLIENT_AHEAD。
在一种使用情况下,如果交付语句(由于前台或实例或网络的消息丢失而)未返回客户端,那么客户端就挂起。在FAN事件或错误消息到达之后,应用程序可以调用GET_LTXID_OUTCOME,或者如果使用failover_mode(故障切换模式)是TRANSACTION的重新运行驱动程序,那么重新运行驱动程序就调用隐藏在GET_LTXID_OUTCOME中的PREPARE_REPLAY。
在一种使用情况下,调用PL/SQL程序包中的GET_LTXID_OUTCOME以利用当前的逻辑TXID确定输出。GET_LTXID_OUTCOME的结果可以包括:COMMITTED=TRUE且USER_CALL_COMPLETED=TRUE表示跟该LTXID相关联的事务已交付并完成;COMMITTED=TRUE且USER_CALL_COMPLETED=FALSE表示事务已交付。但是在PL/SQL内且该PL/SQL在交付后可能需要也可能不需要向客户端返回信息;COMMITTED=FALSE表示事务未交付;SERVER_AHEAD表示输送的LTXID落后服务器多于一;CLIENT_AHEAD表示输送的LTXID超前服务器多于一;OWN_SESSION表示输送至服务器的LTXID属于当前会话。OWN_SESSION状态作为出错处理以避免会话自锁。
在一种使用情况下,调用内部PL/SQL程序包中的FORCE_OUTCOME以利用当前的逻辑TXID确定输出。FORCE_OUTCOME的结果可以包括:FORCED表示输送的LTXID用阻止的输出交付以使进行中的事务不能交付;COMMITTED表示事务已交付;COMMITTED表示事务在PL/SQL内部交付并且PL/SQL可能已经完成也可能尚未完成;SERVER_AHEAD表示输送的LTXID落后服务器多于一;CLIENT_AHEAD表示输送的LTXID超前服务器多于一;OWN_SESSION表示输送至服务器的LTXID属于当前会话。OWN_SESSION状态作为出错处理以避免会话自锁。
在一个实施例中,客户端在事务已完成后请求交付。在另一些实施例中,客户端可能不知道COMMIT已被执行。例如,隐含交付可以在执行DDL语句而事务仍然有效时出现。作为另一个示例,通过单条DDL语句可以发出若干次交付。在另一些示例中,交付可以在PL/SQL过程或模块内、在存储Java的过程内或者在调出时出现。在很多情况下,利用自动交付代码在应用程序方的服务器上执行交付。该列表绝不是完整的,并且可以有其他的执行隐含交付或附加交付的情况。
在一个实施例中,如果调用在返回给客户端之前并未多于一次地增加LTXID,那就利用FORCE_OUTCOME确定该调用的输出因为服务器和客户端之间单调增加的协议被破坏而得到错误值SERVER_AHEAD。因此,在一个示例中,对于PL/SQL和所有用户调用,无论由该调用发起的COMMIT操作的次数如何,系统给LTXID的增量都不超过一。
对于退回重来以及退回重来到保存点语句,要区分两种不同的情况:
·通过RDBMS的隐含式退回重来
·由应用程序请求的显式退回重来
在一个实施例中,如果事务被放弃,那就调用事务结束回调,但是并不生成新的逻辑事务ID。将相同的逻辑事务ID用于下一个数据库会话。事务退回重来。
在一个实施例中,如果客户端执行“ROLLBACK WORK”语句,类似地在执行事务结束回调时并不生成新的逻辑事务ID。
在一个实施例中,如果在退回重来的输出返回给客户端之前事务失败,那么无论是什么故障事务都退回重来。如果在执行退回重来之前事务失败,那么事务也要通过实例或PMON恢复自动地退回重来。逻辑事务ID并不超前,但是退回重来无论如何都会发生。
在一个实施例中,自动交付事务的处理类似于正常事务。新的逻辑事务ID在关于交付的会话句柄内返回。新的逻辑事务ID允许客户端跟服务器对接以确定在出现停机时自动交付事务的成功。该实施例包括使用导向性的“成功交付(commit on success)”,如果对其明确的调用成功那就可以将其设置用于交付任何开启的事务。
在一个实施例中,如果客户端在开始下一项事务之前就执行语句“settransaction read only(设定事务只读)”,那么事务即被标记为只读。只读事务在redo生成时并不调用回调,原因在于并未针对事务历史表来执行DML。在一个实施例中,逻辑事务ID在针对只读事务交付时并不增加,这样不会改变数据库。在另一个实施例中,尽管只读事务并不改变数据库,逻辑事务标识符除了改变数据库状态的事务以外还可以跟踪只读事务。在一个实施例中,因为只读事务并不改变数据库,所以事务历史表针对只读事务可以不存留记录。
在一个实施例中,如果客户端发出并行DML,那么用户会话就承担并行协调程序的角色并开启父事务。为了执行查询,开启并行查询从属进程并且这些并行从属进程相应地创建其自身事务。这些从属事务被链接至父事务。如果任何从属事务在相同或单独的数据库实例上失败,那么父事务及其所有从属事务都退回重来。在一个示例中,由于从属事务是通过父事务关联,因此只有父事务跟逻辑事务ID相关联。逻辑事务ID被插入或更新到关于查询协调程序定位于此的数据库实例的事务历史表内。
在一个实施例中,对于读/写数据库,本地数据库的命名空间被用于LTXID。如果这是只读数据库或有效的数据保护,那么数据库链接可以指回主数据库。在回送的情况下,协调程序可以写入事务表。1PC优化也可以生效。
在一个实施例中,两阶段交付机构确保所有的节点都共同交付或执行退回重来。如果在有准备调用之后三个阶段中有任何一个因为系统或网络错误而失败,那么事务就变为存疑。恢复(“RECO”)过程在机器、网络或软件问题解决后自动解决存疑事务。直到RECO解决事务为止,数据都被锁定不得读写。数据库在更高的SCN阻止读取。在很多示例中,数据库自动解决存疑事务。这样还解决了跟该事务相关联的LTXID。
在一个实施例中,如果分布式事务仍然待决,那么获知事务输出可以延迟。直到解决分布式事务之前,事务结果都不返回给用户。另外由分布式事务保持的锁定也可以阻止其他的用户会话。
在一个实施例中,客户端发起XA事务。XA事务包括一个或几个事务分支。这些事务分支通过相同的全局事务ID(“GTRID”)关联。GTRID在XA会话和事务表中设定。Oracle数据库支持紧密耦合的分支和松散耦合的分支。紧密耦合的XA事务分支被串联执行。同一件XA事务的几个事务分支不并行执行。一个事务分支在开启一个新事务分支之前关闭(事务分支的关闭可以被隐含地调用)。每一个事务分支都具有其自身的LTXID和相同的GTRID。在一个实施例中,逻辑事务ID未被用于XA事务,改为记录GTRID以获知事务输出。
在一个实施例中,(每一个数据库中)只有生成XA事务redo的第一分支插入GTRID历史表内。另外的事务分支不对事务历史做出改变。在另一个实施例中,第一分支用于准备和清除redo,处理记录GTRID的交付前触发程序。
在一个实施例中,客户端例如Weblogic服务器和Tuxedo拥有其自身的全局唯一事务标识符GTRID。这些唯一的事务标识符可以被提供作为记录在事务历史中的GTRID。
在一个实施例中,XA事务的所有分支都有相同的GRID。Weblogic服务器的GTRID全局唯一并且被保存在http会话状态内。存留一个连接在事务的生命期内使用,并且设置GTRID和容器ID来取代LTXID。在共享连接时,检查第一事务的GTRID以在恢复其他事务之前确认第一事务的GTRID是否在http会话状态内。
在一个实施例中,调用函数XAstart以建立新的事务分支。XAstart导致GTRID的分配并且设定事务状态对象内的事务位和会话句柄。XAstart的调用是使用XA数据源时在XA协议中的第一步。在执行XAstart函数调用之前不能执行查询。每一条分支都有分支限定符。
图7示出了可以在数据库系统内执行的示例性分布式事务。如图所示,事务分支708延伸在XAstart调用706和XAend调用710之间。
在一个实施例中,每一个数据库和事务中最多能有32个分支限定符。分支限定符针对事务内的每一个资源分区从一开始计数。XA事务的每一个分支都有相同的GTRID。
事务针对包括那些只读内容的所有XA会话开始。为了避免在没有redo时生成redo,用于LTXID/GTRID记录的交付触发程序在第一次redo生成时注册。这样就可以不在第一分支上。
一种用于XA的示例性使用情况包括以下步骤:
1.XA开始(第一事务分支)
2.查询
3.XA结束(第一事务分支结束,未插入LTXID映射,这就意味着我们可能无法向第一分支内插入映射从而使得恢复更加困难)
4.XA开始(第二事务分支)
5.查询
6.插入(这就意味着我们还应该插入事务历史表)
7.XA结束
在一个实施例中,1PC优化禁止XA会话进入存疑状态(只有一个会话分支交付以使其不能变为存疑)。如果事务分支被分配到相同的事务表,那就支持1PC交付优化。客户端继续向所有分支而不是最新分支发布XAprepare。其他的事务分支清除关于准备的重做并返回只读。1PC优化被设置在交付调用中以避免对最新事务分支的XAprepare调用。如果未将所有分支用于相同的实例,那就拒绝1PC优化。
在一个实施例中,XA事务可以用两种不同的模式运行:紧密耦合和松散耦合。紧密耦合的XA事务可以是默认模式。每一个分支都可以看到其他事务分支的未交付改变。紧密耦合的XA事务严格地串行而不是并行执行。如果事务分支没有在开始新的事务分支之前明确结束,那就执行隐含的XAend以终止先前的事务分支。WebLogic服务器支持紧密耦合模式。
松散耦合的XA事务独立且无法看到彼此的改变。松散耦合和紧密耦合的XA事务都能变成存疑。1PC优化可以避免事务变为存疑。事务幂等性被用于利用GTRID获知用于1PC优化事务的输出。
本地事务和XA事务在存留交付输出方面的一种差异在于本地事务使用LTXID而XA事务使用GTRID。事务可以作为本地事务开始但是随后转化为XA事务。这种类型的事务被称为可提升的XA事务。在一个实施例中,如果事务可提升,那就在事务交付时插入GTRID而不是LTXID并且不再生成新的LTXID。
在一个实施例中,在客户端已于停机后重连之后,客户端调用强制输出函数以插入或更新跟先前会话相关联的LTXID。插入/更新将LTXID标记为阻止。应用程序随后即可通过新的LTXID(在建立会话时创建的LTXID)安全地重新运行事务或者向应用程序返回最终事务的输出或者采取下一步的动作。
在一个实施例中,GET_LTXID_OUTCOME函数可以具有以下输出:取值为TRUE/FALSE的COMMITTED以及取值为TRUE/FALSE的USER_CALL_COMPLETED再加上ERROR。如果事务已交付并完成,那么函数就返回COMMITTED=TRUE和USER_CALL_COMPLETED=TRUE;如果交付在PL/SQL模块或存储java的过程内执行且不是PL/SQL模块内的单次COMMIT和最后一次调用或者如果还有更多数据要通过COMMIT返回,那么函数就返回COMMITTED=TRUE和USER_CALL_COMPLETED=FALSE。如果事务尚未交付或者先前已被阻止,那就返回COMMITTED=FALSE。
在一种使用情况下,强制输出函数的返回代码被映射至以下的重新运行操作:
·COMMITTED=TRUE和USER_CALL_COMPLETED=TRUE被映射至CONTINUE
·COMMITTED=TRUE和USER_CALL_COMPLETED=FALSE被映射至COMMITTED/NO_REPLAY
·COMMITTED=FALSE
另外的错误代码
·SERVER_AHEAD被映射至NO_REPLAY/ERROR
·CLIENT_AHEAD被映射至NO_REPLAY/ERROR
·OWN_SESSION被映射至NO_REPLAY/ERROR
在一个实施例中,强制输出函数可以具有以下的输出:COMMITTED、EMBEDDED、FORCED再加上ERROR。如果事务已交付,那么函数就返回COMMITTED,如果交付在PL/SQL模块或存储java的过程内执行且不是PL/SQL模块内的单次COMMIT和最后一次调用,那么函数就返回EMBEDDED。如果事务尚未交付或者先前已被阻止,那就返回FORCED。
在一种使用情况下,强制输出函数的返回代码被映射至以下的重新运行操作:
·COMMITTED被映射至CONTINUE
·FORCED被映射至REPLAY
·EMBEDDED被映射至NOCOMMITTED/NO_REPLAY
另外的错误代码
·SERVER_AHEAD被映射至NO_REPLAY/ERROR
·CLIENT_AHEAD被映射至NO_REPLAY/ERROR
·OWN_SESSION被映射至NO_REPLAY/ERROR
在一个实施例中,如果事务已经更新事务历史表内的记录并且记录行被锁定,那么强制输出函数就一直等待到先前事务完成。如果因为事务存疑而锁定行,那么FORCE_OUTCOME也要等待。
在一个实施例中,如果事务在故障切换之后重新运行,那么就通过强制输出函数来再次阻止LTXID。强制输出阻止带有相同LTXID的运行中事务免于交付。新的LTXID(跟客户端重连/故障切换的会话相关联)被用于重新运行事务。新的LTXID已经拥有正确的数据库ID和实例ID。
在一个实施例中,如果在重新运行期间尝试交付那就会出现错误。用于重新运行的事务边界跟用于原始事务时相同。在一个实施例中,这种行为包括单次往返行程的事务也就是pl/sql中的自动交付和嵌入交付。在一个实施例中,这种行为排除了对自主事务和递归事务的交付。在一个实施例中,针对应用程序自身的重复运行例如WebLogic Replay允许交付。
在一个实施例中,客户端具有测试LTXID输出的能力。事务输出被存储在会话句柄内。在一个实施例中,除了通过LTXID确定事务状态以外,API被提供用于通过GTRID确定事务状态。在一个实施例中,响应于确定最终事务输出的请求而执行GET_LTXID_OUTCOMEAPI。例如,无需阻止事务完成,查询的事务可以交付,阻止事务的状态使得事务的输出肯定正确。
在一个实施例中,在重复提交时,事务不是已交付就是仍激活。利用来自容器的GET_LTXID_OUTCOME完成这种确定。在另一个实施例中,在插入或更新事务历史表时检测重复提交并且在尝试提交时返回错误信息。在另一个实施例中,在交付时而不是事务开始时检测重复性。
在一个实施例中,在服务激活时禁用commit_outcome服务属性只会影响新的数据库会话。现有的数据库会话继续使用其创建时的commit_outcome服务语义。激活commit_outcome服务属性只会影响新的数据库会话。现有的数据库会话如果还是其创建时的设置那就继续不提供“commit_outcome”语义。
在一个实施例中,数据库管理程序具有针对记录在事务历史表内存储多长时间而明确存留时间的选项。存留时段针对每一种数据库服务可以有所不同。“Retention_Time”服务属性被加入服务定义中。如果未明确存留时段,那就设定24小时的默认值。该时间是从最后一次更新LTXID的时间开始测量直到LTXID变为无效的时段。单位确定为秒。在一个实施例中,当使用GTRID时,GTRID的回收再利用不会超过Retention_Time。
在一个实施例中,定时清理旧记录以确保事务历史表中的记录数量保持较少。只有存留时间窗过期的记录才被删除。检查之间的默认时间间隔是十分钟。可以明确不同的时间段。在一个实施例中,当提取数据库时,推迟/随后清理根据参数发生以避免维护暴增。
在一个实施例中,JDBC和OCI中提供了API:GetLTXID。返回的逻辑事务就是如果未激活事务那就可以用于下一项事务的LTXID。如果有事务在进行中,那么这就是跟该事务相关联的LTXID。这种使用情况是用于客户/应用程序的用户。在一个实施例中,LTXID是随后传输给GET_LTXID_OUTCOME以确定事务输出的不透明对象。
在一个实施例中,客户端具有查询服务的“Commit_outcome”和“Retention_Time”属性的能力。各种视窗提供了该附加信息。
在一个实施例中,Replay_Initiation_Timeout参数被设置为可接受重新运行的以秒为单位的数值。Replay Timeout避免重新运行意外地超过Replay Timeout。计时在第一次错误接收时开始。默认值是300秒,但是也可以规定其他的Timeout值。
在一个实施例中,故障切换之后Web Logic服务器针对容器ID测试有效事务的事务输出。这就要检测针对该容器交付的所有事务。支持在容器停机时确定给所有已交付和完成事务并阻止后续事务针对该容器实体交付的使用情形。
在一个实施例中,请求被作为批量请求提交并且将一批事务输出返回给客户端。如果有效事务比一次答复中能够返回的事务更多,那么就可以请求更多的结果。
在一个实施例中,通过配对地对LTXID应用GET_LTXID_OUTCOME以及对GTRID应用GET_GTRID_OUTCOME而安全地实现用于输出的测试,它们是在已交付和尚未解决的事务之间扫描之后的差值。
在一个实施例中,通过针对该容器实体阻止后续事务交付而安全地实现用于输出的测试。
在一个实施例中,根据机器规格和并发事务的数量,数据库管理程序可以增加/减少每一个数据库中用于事务历史表的数据库分区的数量。
在一个实施例中,事务幂等性支持数据库的整合。事务历史表被存储在可插入的数据库自身而不是根数据库内。当数据库变成不堵塞时,事务历史是可插入数据库的一部分。
在一个实施例中,数据库ID是LTXID键值的一部分。数据库的整合在数据库再次变堵塞时已经确认数据库ID不改变。在一个实施例中,数据库的整合避免同一个可插入数据库在同一个根数据库内多次堵塞。
在一个实施例中,LTXID属于每一个连接池并且仅由应用程序会话在校验的时段内拥有。在释放后,LTXID随连接池一起存留。在另一个实施例中,LTXID属于应用程序。
在一个实施例中,LTXID和光标重现带有DBID以避免冲突。LTXID受到DBID和InstanceId的限制。在一个实施例中,如果会话尝试应用LTXID时存在间隙,那么故障切换就根据情况而被拒绝成为CLIENT_AHEAD或SERVER_AHEAD。
在一个实施例中,如果数据库已被复位,那么测试LTXID的输出就由于要分配该数据库而拒绝。也就是说,数据库已经通过复位日志打开且已丢失数据。数据库实体由复位日志改变。因为这是用于只读故障切换的同一个DBID/实体,所以有效数据保护延迟可以得到支持。
在一个实施例中,数据库超前或滞后的行为根据事务幂等性的使用情况而略有不同。
在一个实施例中,为了在同一个数据库上公开使用,如果数据库已经相对于客户端在时间上后移,那么GET_LTXID_OUTCOME就返回错误输出。
在一个实施例中,为了在另一个数据库上公开使用,GET_LTXID_OUTCOME的行为取决于是否复制了该LTXID。如果答案为是,那么GET_LTXID_OUTCOME是否返回错误输出取决于复制是否完成。如果答案为否,那么除非交付编号为零,否则GET_LTXID_OUTCOME就返回SERVER_AHEAD或CLIENT_AHEAD之一。对于零(不可见),LTXID被阻止。
在一个实施例中,对于驱动程序重新运行,OPI管理层查询事务位的最新输出和客户端已知的语句并确定事务是否能够激活。如果事务不能激活,那就不调用FORCE_OUTCOME。这就避免在无事务的故障切换时创建事务。
在一个实施例中,对于驱动程序重新运行,将光标重现场景携带的数据库签名跟已经故障切换过的数据库相比较。签名包括数据库ID、数据库实体和打开的时间标记。对于事务,如果做出决定调用FORCE_OUTCOME,那每一个LTXID都继续应用CLIENT_AHEAD和SERVER_AHEAD错误。对于读取,重新运行能够在完成请求时的当前时间进行。
在一个实施例中,当有效数据保护在DML转发模式下使用时,LTXID在主数据库被插入送回。在有效数据保护的数据库中不进行插入LTXID的尝试。主数据库是关于事务的信息来源。待机能够以交付编号0生成LTXID。但是,插入是在主数据库并且交付是在主数据库,而更新的LTXID被返回给有效数据保护。这种功能依赖于已知服务或对象所用的DML转发。
在一个实施例中,如果数据库支持DML转发,那么LTXID就在有效数据保护的会话创建时生成。交付前后的触发程序在第一次redo生成时注册以在主数据库执行。COMMIT通过LTXID转发至主数据库。增加的LTXID被返回给有效数据保护。而且,FORCE_OUTCOME也在主数据库执行。
在一个实施例中,服务器提供“commit_outcome”服务以支持应用程序故障切换和重启。服务器还可以支持replay_initiation_timeout服务属性以明确重新运行何时不应再继续重试的超时值,还可以支持Retention_Time服务属性以使不同的服务能够获得不同的存留时段。服务器还支持在服务有效时改变commit_outcome服务属性。现有的数据库会话在存留其初始commit_outcome服务属性的服务中开始。
在一个实施例中,用户利用称为commit_outcome的服务属性通过数据库会话连接。如果针对服务设定了该属性,那就要创建逻辑事务ID;否则服务器就不再记录事务。
图3示出了用于在事务开启并且执行数据定义语言(“DDL”)的语句时保存数据库系统内事务输出的示例性步骤。
以下列表更加详细地介绍了示例性步骤:
1.客户端连接至数据库实例(步骤314)
2.服务器建立新的LTXID并将其返回给客户端以作为连接握手的一部分(步骤318)
3.客户端执行第一条SQL语句(步骤324)
4.服务器向客户端返回结果(步骤328)
5.客户端执行更多SQL语句(步骤336)
6.在第一次redo生成时,注册交付前和交付后的回调(步骤340)
7.目前未对先前情况做出任何改变,此时仅执行了DML
事务在此有效,此时执行DDL命令。图4详细示出了更多示例性步骤。
以下列表介绍了各个步骤:
8.向服务器发送DDL语句(步骤432)
9.服务器发出隐含交付(步骤436)
10.调用改变LTXID状态的交付前触发程序。LTXID在此时超前(步骤440)
11.服务器执行DDL语句(步骤446)
12.服务器调用隐含交付(步骤450)
13.在第一次redo生成时,服务器再次注册两种事务交付回调。另外服务器还将内存中的LTXID状态设定为COMMITTED(步骤452)
14.交付前触发程序在交付时更新事务历史表。交付后触发程序被调用并增加LTXID(步骤456)
15.将新的LTXID(原始运行交付编号被增加两次)和交付状态返回给客户端(步骤442)
在一个实施例中,TRUNCATE DDL被实施作为递归事务套件。它们作为递归事务执行并且可以具有两个阶段。为此交付回调并不针对TRUNCATE自身注册,除非是加入标记事务以强行设定顶层交付。
在一个实施例中,如果DML在执行TRUNCATE操作时打开,那么该用户事务就被预先注册并隐含交付。执行该交付的动作增加LTXID中的交付编号。但是,因为TRUNCATE自身单独递归,所以就不会出现LTXID的第二次递加。
在一个实施例中,当驱动程序代理服务器或WebLogic服务器或第三方会话失败时,它们首先获取新的会话,其中该会话拥有自身的逻辑事务ID。然后他们利用客户端驱动程序提供的API-用于JDBC的getLTXID以及用于OCI的OCI_ATTR_GET和LTXID从先前失败的会话中获取LTXID。客户端(驱动程序或WebLogic或其他应用程序)调用GET_LTXID_OUTCOME函数,其中LTXID从API中获取。如果LTXID尚未被使用或者比上一次使用的LTXID多一或者为零,那就将故障切换会话中的原始LTXID标记为阻止。返回的输出告知驱动程序是否已经交付了最终事务。在一种使用情况下,未交付的事务可以用新的逻辑事务ID(跟新创建的会话相关联的LTXID)重新运行。如果该重新运行自身遭遇停机,那么重新运行会话所用的LTXID即被用于GET_LTXID_OUTCOME函数。在另一种使用情况下,输出被返回至应用程序。
在一个实施例中,如果会话被连接至未设置commit_outcome属性的服务,那么服务器就不再记录事务。图5示出了用于在数据库管理系统内执行事务性命令集的示例性步骤。客户端在步骤514连接至数据库并创建新会话,但是不再创建逻辑事务ID或返回给客户端。在步骤518和522,客户端能够在开启事务之前发出请求。当客户端在步骤526-532开启新事务时,不执行对事务历史的插入或更新。客户端可以在步骤526-532执行一条或多条DML语句并随后在步骤536-542交付事务。在交付期间,如果未针对会话设置commit_outcome属性,那就不生成新的逻辑事务ID。
在一个实施例中,自动交付事务的处理在逻辑事务ID方面跟其他的数据库会话相同。逻辑事务ID在交付时被自动存留,并且逻辑事务ID可以被用于在停机时确定自主事务的输出。一种示例性的差异是每一条顶层SQL语句都在其自身的数据库事务中执行。在每一项数据库事务结束时,逻辑事务ID中的交付编号部分被递加并在交付消息中返回。对于PL/SQL模块,自动交付模式导致在模块完成执行后PL/SQL模块结束时交付。
在一个实施例中,对于XA,仅有生成每一个数据库中redu的第一事务分支记录GTRID。映射被存储在跟LTXID不同的表内;该表被称为GTRID事务历史表。GTRID是唯一的并且被存储在GTRID事务历史表内。
在一个实施例中,如果事务分支在调用边界期间分配了事务状态对象,那就生成redo并且事务激活,GTRID被插入GTRID事务历史表内。
在一个实施例中,GTRID映射在跟会话分支相关联的DX排队锁定值从NULL变为调用边界的不同值时存留并且生成redo。事务的事务分支跟相同的GTRID关联。
在一个实施例中,WebLogic服务器设定Container ID和GTRID。这些内容在连接句柄上传递至服务器用于每一项全局事务。
在一个实施例中,当使用XA数据源时,WebLogic服务器发出XAstart调用作为对每一个连接的第一个动作,以使事务立即开启。操作从未处于仅作选择的阶段。在一个实施例中,WebLogic服务器在XAstart时对每一个参与的会话设定相同的GTRID以关联事务分支。在一个实施例中,每一项事务都包括以下步骤:
1.XAstart
2.XAend
3.XAprepare(如果唯一来源是该XA事务的一部分则不需要XAprepare)
4.XAcommit
在一个实施例中,LTXID事务历史表被分区并且实例ID是分区键值的一部分。如果仅有一个实例更新或插入分区内,则实例自动更新实例亲合力。作为优化,亲合力可以在数据库实例启动时立刻强行设定。
在一个实施例中,用于逻辑事务ID的事务映射被存储用于确定时段,并且驱动程序/应用程序可以查询LTXID映射。在该存留时段过期后,逻辑事务的输出即可删除。一旦删除,这些事务的输出就不能在根据LTXID映射确定。
在一个实施例中,不同的存留时段被用于不同类型的工作负荷。例如,OLTP应用程序用3-6小时的存留时段即可非常好地工作。另一方面,具有长运行事务的批量应用程序用24小时的存留时段可能工作得更好。存留时段可以明确作为新的服务属性。如果未明确取值,那就使用24小时的默认存留时段。最小值是十分钟。存留时段是一种服务属性。
在一个实施例中,在停机期间,会话从一个数据库实例故障切换到另一个数据库或实例。为了重新运行最终事务,驱动程序可以用两种方式确定最终逻辑事务的输出。如果最终逻辑事务已经成功交付或者数据库超前或落后,对具有该相同LTXID的COMMIT的下一次尝试就因违反约束条件而失败(LTXID已插入或脱离跟LTXID事务历史表内的同步)。
在一个实施例中,FORCE_OUTCOME操作确定用于以下状态:
·存留
·冲突
·客户端超前
·服务器超前
·相同的会话
·存疑(GTRID已设定但是不在GTRID事务历史表内)(悬而未决)
·错误
在一个实施例中,事务历史表被有规律地清理。MMON可以调用清理函数。两种示例性的超时动作包括:
·每隔60分钟就存留其数据库实例中的过期事务历史记录
·每隔12小时就存留所有数据库实例中的过期事务历史记录一个数据库实例就可以执行这种类型的清理。
在一个实施例中,当用户认证新会话时,创建新的逻辑事务ID。可以执行以下的示例性步骤:
检查是否设定了服务的commit_outcome属性
确定数据库ID和实例ID并存储在LTXID结构中
调用guid函数以建立会话ID并存储在LTXID结构中
在LTXID结构中将交付编号设为0
在一个实施例中,当用户检查连接池中的会话时,会话的LTXID就跟该用户相关联。这种关联保持就位直到会话返回连接池为止。
在一个实施例中,在第一次redo时,注册交付前和交付后的事务回调。交付处理包括三项步骤:
·交付前回调
·事务交付
·交付后回调
交付前回调是用于插入或更新LTXID记录。这种回调检查某些约束条件。在一个实施例中,回调在这些条件下不向事务历史表内插入:
·数据库为只读
·事务在待机数据库中
·有效数据保护的实例
·数据库处于未登录模式
·事务为只读
·自主事务
·不是首次改变XA事务
·PDML事务的从属事项
·递归事务
针对交付前回调要区分两种示例性情况:
·用户会话中的第一项事务
从用户会话结构中获取逻辑事务ID
在LTXID事务历史表中插入新的行
设定开始日期
设定事务ID
设定状态
·用户会话中的后续事务
从用户会话结构中获取逻辑事务ID
更新事务历史表中的行(如果行内的交付编号落后一的话)
设定开始日期
设定事务ID
设定状态
可以从内部force_outcome api返回的三种示例性状态包括:TOPLEVEL_COMMITTED、EMBEDDED INTERNALLY_COMMITTED和BLOCKED。在一个实施例中,在交付前触发程序执行期间,仅使用前两个状态。如果使用标准SQL,那么LTXID状态就是TOPLEVEL_COMMITTED。如果交付作为PL/SQL模块的一部分执行并且还有更多数据要通过交付返回客户端例如随自动交付而进行,那么状态就被设定为EMBEDDED INTERNALLY_COMMITTED。该示例将普通交付跟调用内部执行的交付例如PL/SQL模块或自动交付区分开。例如作为PL/SQL模块的一部分执行的交付不能保证PL/SQL模块完成。
在事务交付之后,调用交付后触发程序。交付后触发程序增加逻辑事务ID的运行交付编号以建立下一个LTXID。下一个LTXID被送回客户端作为交付消息的一部分。(对于XA事务,由于GTRID被唯一地用于每一项TX而省略递加动作)
在一个实施例中,交付触发程序可能失败并出现错误。在交付前触发程序的情况下,事务被退回重来。在交付后触发程序的情况下,如果只有LTXID中的交付编号部分增加,那么就认为没有出错。在有错误的情况下生成报错信息并返回给客户端。
在一个实施例中,对于XA事务,映射被插入到GTRID事务历史表内。在一个实施例中,因为每一个GTRID都不同且由客户端提供,所以不执行更新操作。
在一个实施例中,在插入或更新事务历史表之前,验证运行交付编号的正确性:只有单调增加的数值才被接受。句柄上LTXID的交付编号值应该比存储在事务历史表中的值超前一。
在一个实施例中,定义例外句柄以缓存通过插入或更新事务历史表造成的完整性破坏。捕捉这种完整性破坏错误并且改为给出新的用户错误以促进错误诊断。这就使得可以通过错误编号识别错误的根本原因。
在一个实施例中,如果在同一个PL/SQL模块内执行了多次交付,那么只有第一次交付增加LTXID,并且作为PL/SQL模块的一部分而执行的后续交付并不增加LTXID的交付编号。在本实施例中,每一次往返行程对LTXID的交付编号的冲击最多只有一。
在一个实施例中,如果在来自客户端例如DDL、PL/SQL、Java的往返行程中出现了多次交付,那么只有第一次交付增加LTXID,并且作为往返行程的一部分而执行的后续交付并不增加LTXID的交付编号。在本实施例中,每一次往返行程对LTXID的交付编号的冲击最多只有一。
在一个实施例中,如果事务被成功交付,那就注册新的事务后调用增加逻辑事务ID的交付编号。如果在故障切换之后已经调用了交付回调并且使用了扩展客户消息,那么逻辑事务ID中的实例ID部分也被更新以反映用户会话的新位置。
在一个实施例中,新的逻辑事务ID在交付消息建立并返回给客户端之前建立。在一个实施例中,该事务交付回调仅在执行语句的会话跟“commit_outcome”服务相关联时才注册。
在一个实施例中,如果针对“commit_outcome”服务明确了COMMIT NOWAIT并且事务输出仍未确定,那么事务回调就不会造成错误。
在一个实施例中,逻辑事务ID以有规律的间隔进行清理。默认间隔是60分钟。在已经超时之后,就通过MMON调用超时动作。
在一个实施例中,清理函数删除来自事务历史表的位于存留窗以外的那些记录。存留窗由跟会话相关的服务的存留时间来确定。在向事务历史表中插入或更新了记录之后,也就设定了expiration_date。
共有两种不同的超时动作:
每一个实例
每一个数据库
在一个实施例中,超时动作在RAC数据库的每一个节点上运行并且每一个数据库实例都负责用于清理其自身创建的记录。这就可以避免来自其他数据库实例的模块转移。
在一个实施例中,当数据库启动后,在接下来的30分钟或者某种其他的特定最小时间量内不出现事务历史表的清理。
在一个实施例中,如果在清理期间遇到错误,那么错误就根据其严重程度而记录到不同的日志中。
在一个实施例中,当客户端连接至数据库且LTXID被专门设定在连接消息中时,调用FORCE_OUTCOME函数以确定最终事务的输出。如果事务已交付,那就生成新的LTXID并随事务输出一起返回给客户端。
在一个实施例中,在交付事务时,新的LTXID作为交付消息的一部分返回给客户端。
在一个实施例中,LTXID信息被存储在服务器和客户端的会话结构中。各个会话ID的尺寸可能过大以至于无法加入会话结构。在一个实施例中,LTXID被存储在新的结构中,并且加入指针以指向新结构中的项目。
示例性数据结构
在一个实施例中,逻辑事务ID是全局唯一的ID,从应用程序的角度唯一性地定义了数据库事务。逻辑事务ID可以包括实例编号、在会话首次连接时分配的逻辑会话guid以及在每一次会话交付工作是更新的运行交付编号。
在一个实施例中,还有GTRID结构用于存储可由客户端提供的附加属性。
在一个示例中,事务历史表被用于记录事务相关信息。下表介绍了示例性事务历史表的定义。表的名称是trans_hist。
在示例中,逻辑事务ID由前四栏构成:db_id、inst_id、session_guid和commit#。主键值包括前三栏。container_id栏可以由客户端通过逻辑事务ID设定为相关的附加属性。例如Weblogic可以使用该栏以存储机器编号。要注意的是任何属性设定在下一次更新LTXID之后都可能变为无效。service_id栏描述了事务已在其中执行的数据库服务。start_date栏在交付事务时存储以用于确定事务历史表内的记录能否删除。State栏描述了事务状态,例如用于确定事务是否已在PL/SQL内交付。ntss_state栏使得可以存储跟逻辑事务相关联的非事务状态设定。
下表介绍了示例性GTRID事务历史表的结构。表的名称是trans_table_xa。在示例中,instance_id栏被用于区分插入和减少正常操作期间的呼叫量。service_id栏被用于确定何时能够删除记录。存留时间是一种服务属性。
在一个实施例中,LTXID事务历史表被分区。在一个实施例中,旧记录在循环中以“懒散”的方式进行清扫。
在一个实施例中,用户会话结构被扩展用于存储逻辑事务ID。在一个实例中,指针被加至用户会话结构中以指向新的LTXID结构。新的LTXID结构使用跟用户会话结构相同的内存管理和索引方案
在一个实施例中,LTXID结构存储会话中的当前和下一个LTXID。本方法避免了如果需要新LTXID的新客户端到达就要访问服务器的往返行程。本方法只有客户端在其生命期内存留LTXID而不是在登录时将LTXID返回给连接池才能有效。
示例性服务属性
在一个实施例中,数据库服务具有三种附加的服务属性:
·交付输出(Commit outcome)
·存留时间(Retention time)
·重新运行的初始超时(Replay initiation timeout)
commit_outcome属性确定了针对服务是否生成并存留逻辑事务ID。如果在用户会话已利用该服务连接时激活了commit_outcome属性,那么只有新会话才能利用改变的设置并建立逻辑事务ID。如果commit_outcome属性被关闭,那么只有新用户的会话不创建逻辑事务ID;现有的用户会话仍然使用逻辑事务ID。
在一个实施例中,DBMS_SERVICE程序包改变以下的两种过程并向其中加入两个另外的参数:
·CREATE_SERVICE
·MODIFY_SERVICE
在一个实施例中,用于Retention_Time属性的默认值是24小时,且最大值是30天。在一个实施例中,用于replay_Initiation_timeou属性的默认值是5分钟,且最大值是3天。
Retention_Time属性确定了LTXID在事务历史表中存储多长时间。在超时之后,记录就可以从事务历史表中删除。
在一个实施例中,replay_initiation_timeout确定了重新运行能够重试多长时间。
示例性接口
在一个实施例中,当HTTP请求首次登录时就从连接池中校验得到连接。如果要在会话中交付事务,那么该连接就存留要使用的下一个LTXID。LTXID被复制到http会话的cookie中。
在一个实施例中,如果针对未激活commit_outcome属性的会话调用函数,那就返回NULL。
在一个实施例中,作为故障切换的一部分,客户端驱动程序调用强制输出过程。该过程即使在故障切换处理期间也存留最多执行次数的语义。如果带有LTXID的事务需要为了返回输出COMMITTED=FALSE而被阻止,那么事务GET_LTXID_OUTCOME过程就通过输入的LTXID得到对事务历史表的插入和更新。
针对LTXID的有效指针被送入外部GET_LTXID_OUTCOME函数。函数结果可以包括以下的一种示例性状态:
·COMMITTED=TRUE(事务已交付)
·COMMITTED=FALSE(事务未交付)
·USER_CALL_COMPLETE=TRUE用户可以在交付后无附加动作地运行完成
·USER_CALL_COMPLETE=FALSE交付在PL/SQL模块或存储java的模块内出现或者要返回更多数据
·ERROR(因为内部错误或者服务器或客户端超前或者在跟LTXID相同的会话中调用了FORCE_OUTCOME)
在一个实施例中,如果交付编号为0,那么强制输出函数就在事务历史表内插入新纪录并将记录标记为“阻止”。
在一个实施例中,WebLogic服务器能够通过明确ContainerID和容器实体的组合来检索事务状态。这就唯一地识别了由该容器实体发出并交付的所有事务。调用一次。不再接收从该容器和实体交付更多的事务。
在一个实施例中,客户端API为应用程序提供针对事务历史表查询逻辑TXID输出的能力,建立LTXID并通过会话句柄向客户端返回LTXID的能力,查询WebLogic服务器容器的事务输出的能力。客户端API还可以支持PL/SQL API以利用FORCE_OUTCOME查询LTXID的状态。
在一个实施例中,具有过程GET_LTXID_OUTCOME的PL/SQL程序包由客户的应用程序和第三方应用程序的服务器在会话变为不可用时用于确定最新会话的事务性输出。
GET_LTXID_OUTCOME可以被用于确定新的可用会话中的进行中的事务是否已交付。在初始会话由于不可用而返回错误时使用该过程。能够造成这种会话不可用性的情况包括会话、实例、服务器或网络的计划内或意外的停机。在出现这样的停机时,应用程序接收连接断开的报错。这种错误不提供关于应用程序是否交付事务的判断,也不提供是否应该返回应用程序希望从该交付中获得的状态。
在一个实施例中,由应用程序执行以下步骤以确定是否交付最终事务。
1.第一步骤是获知是否由于丢失了对数据库的访问而报错。OCI和JDBC驱动程序均提供用于检查接收到的错误是否“可恢复”的接口。捕捉用于JDBC和OCI属性的可恢复例外:用于OCI的OCI_ATTR_IS_RECOVERABLE。
2.一旦得知例外可恢复,接下来就使用由每一种OCI和JDBC驱动程序提供的API以获得现已不可用的会话所使用的LTXID。LTXID是不透明的结构。LTXID由于不断改变而在使用之前立刻检索。如果使用了更早时间前获取的旧LTXID,那么LTXID就无效并且会导致拒绝。
3.应用程序现在获取新会话。这可以是池中的会话或新会话。
4.在新会话中调用过程GET_LTXID_OUTCOME以获知最后的调用是否交付。根据该过程的输出,应用程序可以向用户返回交付状态。如果没有交付,那么在请求之间无状态的应用程序能够针对使用请求的应用程序重新提交最新的完整请求。
在一个实施例中,在接收到可恢复的停机之后,应用程序从旧会话获取LTXID。这就返回了包含LTXID的不透明对象。应用程序随后获取新会话并调用PL/SQL GET_LTXID_OUTCOME和LTXID以获得会话的最新输出。
如果使用基于JDBC的容器例如Weblogic(或第三方),那么LTXID就可以通过由JDBC驱动程序提供的事件在http会话cookie中变为可用。在停机之后,容器包含新会话并调用cookie内保存GET_LTXID_OUTCOME和LTXID以获得事务输出。如果使用了JDBC瘦驱动程序或JDBC OCI驱动程序,事件无需容器即可使用。
在调用GET_LTXID_OUTCOME之后,应用程序得到返回的两个布尔值:返回COMMITTED用于获知调用是否交付,以及如果应用程序预期有附加数据例如PL/SQL输出赋值或跟COMMIT一起返回的DML或者如果COMMIT中途通过PL/SQL那就返回USER_CALL_COMPLETED。示例性方法通过三种示例性情况继续:
1.如果COMMITTED布尔值是false且USER_CALL_COMPLETED布尔值是false,那么调用就没有执行任何交付。
2.如果COMMITTED布尔值是true且USER_CALL_COMPLETED布尔值是true,那么调用就执行过交付并且没有要返回的附加信息或者如果调用是Pl/SQL或自动交付或由于在成功设定后有用户调用和交付没有更多工作要做。
3.如果COMMITTED布尔值是true且USER_CALL_COMPLETED布尔值是false,那么事务确实执行了交付并且还有附加信息要返回或者还有更多工作要做。应用程序可以需要也可以不需要后者。USER_CALL_COMPLETED是false时的示例包括多行消息改变以及用于能够从更高层调用的PL/SQL过程。
在一个实施例中,应用程序可以在情况(1)重新提交最新请求。对于情况(2),应用程序可以向终端用户返回已交付。但是,应用程序如果预计交付应该返回数据那可能就不再继续。应用程序可以确定其是否想要获知事务有没有交付(true/false)或者其是否需要附加状态。
在一个实施例中,如果客户端在重连后不再跟服务器同步,那么过程GET_LTXID_OUTCOME就返回错误代码以指示客户端超前或服务器超前。如果数据库已经闪回或者有数据保护并打开较早或者经历了介质恢复,那就有可能会出现客户端超前。如果旧状态LTXID被传递给GET_LTXID_OUTCOME,那么PL/SQL就返回指示服务器超前的错误。
在一个实施例中,客户端可以执行以下过程:
1.客户端接收FAN向下中断或错误
2.确认错误可恢复(来自OCI的新接口或用于JDBC的现有例外类)
3.从利用OCI和JDBC提供的API从旧会话句柄获取最新的LTXID
4.获取新会话
5.通过最新LTXID调用PL/SQL过程GET_LTXID_OUTCOME,返回committed和user_call_completed的布尔值
6A.如果已交付且用户调用已完成,那就返回已交付并继续
6B.否则如果已交付且用户调用未完成,那就返回已交付和应用程序无法继续的消息(如果应用程序需要返回数据)或者如果应用程序无状态且不需要该数据那就继续
6C.否则如果未交付,可选地在客户端清理任何应用程序的状态改变并重新提交最新请求
安装、调节、配置和诊断
在一个实施例中,用户能够通过设定存留时段来影响存储需求。例如,较长的存留时段跟较短的存留时段相比可以使用更多存储资源。
在一个实施例中,只有新会话才有重新运行的能力,并且管理员在设定改变后选择断开现有用户以促使用户获取新会话。这可以利用FAN完成以在重新登录时不将会话返回池中。
在一个实施例中,如果使用了“commit_outcome”服务,那么工作可以故障切换至另一个数据库实例。在新服务创建时,数据库管理员可以确定这是不是“commit_outcome”服务以及相关的存留时段有多长。
在一个实施例中,服务器提供接口以允许调试逻辑事务ID到数据库事务ID的映射记录以及事务幂等性系统的其他应用。
在一个实施例中,事务历史表在利用事务幂等性之前创建。例如,表格可以利用PL/SQL程序包创建。程序包被用于安装和卸载功能所需的对象。例如,程序包创建用于存储LTXID的表格。弃用过程可以删除这些表格。
在启动期间,服务器代码应该检测是否创建了事务幂等性表格。如果表格已经创建,那就可以设置SGA变量并激活应用程序的完整功能。
在一个实施例中,当新实例被加入RAC数据库时,如果分区尚未创建,那就加入新的分区。如果数据库是RAC或者正在补充的数据库是处于数据保护或有效数据保护农场的RAC数据库,那就可以预先加入分区。这一点在使用RAC时对于实施来说很重要。
设计使用分区以确保事务历史表在数据库实例上以及在各个数据库实例内执行良好。在运行时事务仅插入或更新本地分区。在故障切换时,强制性操作使用旧的实例ID。重新执行继续将实例ID用于新实例。
在一个实施例中,如果不再需要幂等性,那么事务历史表就可以弃用。在重新执行期间弃用事务历史表可以导致错误。
在一个实施例中,事务幂等性通过设定用于服务的属性COMMIT_OUTCOME而在服务中实现。用于事务幂等性的保持时段可以利用RETENTION_TIME调节。对于大多数应用程序,24小时应该就足够了。
COMMIT_OUTCOME在COMMIT已执行之后确定事务的COMMIT输出是否可以访问。在COMMIT持久时,该特征就使COMMIT的输出也持久。所述特征用于应用程序以查询在停机后最后一次执行的交付的输出。该特征由Replay Driver、Web Logic Replay使用并且可供用于其他的应用程序以确定最后一项处理事务的输出。
RETENTION_TIME跟COMMIT_OUTCOME结合使用。确定维持COMMIT_OUTCOME的时间量
硬件概述
根据一个实施例,本文所述的技术通过一种或多种专用计算设备实施。专用计算设备可以是实现所述技术的硬接线式设备,或者可以包括数字电子设备例如一种或多种持续编程以实现所述技术的专用集成电路(ASIC)或现场可编程逻辑门阵列(FPGA),或者可以包括一种或多种编程以根据固件、内存、其他存储器或其组合内的程序指令实现所述技术的通用硬件处理器。这些专用计算设备还可以将定制的硬接线逻辑、ASIC或FPGA跟定制的编程相结合以实现所述技术。专用计算设备可以是桌面计算机系统、便携式计算机系统、手持设备、联网设备或者是加入硬接线和/或程序逻辑以实施所述技术的任何其他设备。
例如,图15是示出了可以在其中实施本发明实施例的计算机系统1500的方块图。计算机系统1500包括用于交流信息的总线1502或其他通信机构,以及跟总线1502耦合用于处理信息的硬件处理器1504。硬件处理器1504可以是例如通用微处理器。
计算机系统1500还包括主内存1506例如耦合至总线1502用于存储信息以及由处理器1504执行的指令的随机存取存储器(RAM)或其他动态存储设备。主内存1506还可以在执行应由处理器1504执行的指令期间用于存储临时变量或其他中间信息。这样的指令当存储在可供处理器1504访问的非瞬时性存储介质中时就让计算机系统1500成为定制用于执行指令中明确的操作的专用机器。
计算机系统1500进一步包括耦合至总线1502用于存储静态信息和指令供处理器1504使用的只读存储器(ROM)1508或其他静态存储设备。存储设备1510例如磁盘或光盘被设置并耦合至总线1502用于存储信息和指令。
计算机系统1500可以通过总线1502耦合至显示器1512例如阴极射线管显示器(CRT)用于向计算机用户显示信息。包括字母数字键和其他键的输入设备1514被耦合至总线1502用于跟处理器1504交流信息和命令选择。另一种类型的用户输入设备是光标控制设备1516例如鼠标、跟踪球或光标方向键,用于跟处理器1504交流方向信息和命令选择并且用于控制光标在显示器1512上的移动。该输入设备通常具有沿两根坐标轴的二维自由度,两根坐标轴是允许设备在平面内明确位置的第一坐标轴(例如x)和第二坐标轴(例如y)。
计算机系统1500可以利用定制的硬接线逻辑、一种或多种ASIC或FPGA、跟计算机系统相结合以将计算机系统1500促使或编程为专用机器的固件和/或编程逻辑来实施本文所述的技术。根据一个实施例,本文中的技术通过计算机系统1500响应于处理器1504执行主内存1506中包含的一条或多条指令的一个或多个序列来实施。这些指令可以从另外的存储介质例如存储设备1510读入主内存1506。执行主内存1506内包含的指令序列促使处理器1504完成本文所述的方法步骤。在可选的实施例中,硬接线电路可以被用于取代软件指令或与之结合。
如本文所用的术语“存储介质”是指存储促使机器以特定方式操作的数据和/或指令的任何非瞬时性介质。这样的存储介质可以包括非易失性介质和/或易失性介质。非易失性介质包括例如光盘或磁盘例如存储设备1510。易失性介质包括动态内存例如主内存1506。存储介质的常见形式包括例如软盘、软磁盘、硬盘、固态驱动器、磁带或任何其他的磁性数据存储介质、CD-ROM、任何其他光学数据存储介质、任何具有孔图案的物理介质、RAM、PROM和EPROM、FLASH-EPROM、NVRAM、任意其他的存储芯片或存储盒。
存储介质有所不同但是也可以结合传输介质使用。传输介质参与在存储介质之间传输信息。例如,传输介质包括同轴电缆、铜线和光纤,其中包括由总线1502构成的线缆。传输介质还可以采用例如在无线电波和红外数据通信期间生成的声波或光波的形式。
在将一条或多条指令的一个或多个序列带至处理器1504以供执行时可以涉及各种形式的介质。例如指令可以首先在远程计算机的磁盘或固态驱动器上携带。远程计算机能够将指令载入其动态内存并利用调制解调器通过电话线发送指令。计算机系统1500本地的调制解调器可以接收电话线上的数据并利用红外收发器将数据转化为红外信号。红外探测器可以接收红外信号中携带的数据并且适当的电路即可将数据放到总线1502上。总线1502将数据带至主内存1506,处理器1504从中检索并执行指令。由主内存1506接收的指令能够可选地在由处理器1504执行之前后之后存储在存储设备1510中。
计算机系统1500还包括耦合至总线1502的通信接口1518。通信接口1518提供了跟连接至局域网1522的网络链接1520之间的双向数据通信耦合。例如,通信接口1518可以是综合业务数字网(ISDN)的网卡、线缆调制解调器、卫星调制解调器或者用于为对应类型的电话线提供数据通信连接的调制解调器。作为另一个示例,通信接口1518可以是局域网(LAN)的网卡,用于向兼容的LAN提供数据通信连接。还可以实现无线连接。在任何这样的实施方式中,调制解调器都发送和接收承载表示各种类型信息的数字数据流的电信号、电磁信号或光信号。
网络链接1520通常通过一个或多个网络提供跟其他数据设备之间的数据通信。例如,网络链接1520可以通过局域网152提供跟主机1524或者由互联网服务商(ISP)1526操作的数据设备之间的连接。ISP 1526相应地通过现在通常称为“互联网”的世界性数据包通信网络1528提供数据通信服务。局域网1522和互联网1528都使用承载数字数据流的电信号、电磁信号或光信号。穿过各种网络的信号以及网络链接1520上的信号和经过通信接口1518的信号承载有数字数据且来自计算机系统1500,这些都是传输介质的示例形式。
计算机系统1500能够通过网络、网络链接1520和通信接口1518发送消息和接收包括程序代码在内的数据。在互联网的示例中,服务器1530可以通过互联网1528、ISP 1526、局域网1522和通信接口1518传输应用程序所用的请求代码。
接收的代码可以由处理器1504在收到后执行,和/或存储在存储设备1510或其他非瞬时性存储器内以供最后执行。
示例性实施例
示例性实施例X1-X22包括:
X1、一种方法,包括:
服务器从客户端接收对由客户端先前在会话中发送的所识别的一条或多条命令的集合的输出的请求;其中所识别的一条或多条命令的集合如果在会话中已完成就促使实施:
交付事务的第一服务器操作,以及
向客户端发送所识别的一条或多条命令的集合已交付的指示的第二服务器操作,其中所识别的一条或多条命令的集合已交付的指示直到第一服务器操作已交付事务且完成命令集之后才发送至客户端;
服务器确定由所识别的一条或多条命令的集合促使的至少一项事务已交付以及是否还有由所识别的一条或多条命令的集合促使的任何事务尚未交付;并且
至少部分地基于确定所识别的一条或多条命令的集合内的至少一项事务已交付且所识别的一条或多条命令的集合内至少有一项另外的事务尚未交付,服务器向客户端发送对请求的响应以指示所识别的一条或多条命令的集合内的至少一项事务已交付但所识别的一条或多条命令的集合内至少还有一项另外的事务尚未交付。
X2、如实施例X1所述的方法,其中所述会话是第一会话,其中用于输出的请求在第二会话中从客户端接收,其中所述请求至少部分地基于客户端在第一会话中完成先前的命令集时接收的逻辑标识符识别命令集,并且其中所述响应在第二会话中发送。
X3、如实施例X1所述的方法,其中所述一条或多条命令的集合是从客户端到服务器的单用户调用,并且其中所述单用户调用如果在会话中完成就会促使除了第一服务器操作和第二服务器操作以外的多项服务器操作的实施;其中所述的多项服务器操作促使交付多项改变。
X4、如实施例X1所述的方法,其中所述一条或多条命令的集合如果在会话中完成就会在第一服务器操作和第二服务器操作之间促使至少一项服务器操作的实施;并且其中第二服务器操作如果在会话中完成就会交付对数据库内的一个或多个数据库对象实施至少一项服务器操作的一项或多项临时改变。
X5、如实施例X1所述的方法,其中所述服务器是在多个会话中对数据库提供访问的多个服务器中的第一服务器;其中多个会话中的每一个会话同时最多被分配给一个服务器;其中在会话中由客户端发送一条或多条命令的集合之前,第二服务器在会话中向客户端提供对数据库的访问;其中客户端在第一会话中完成先前的命令集之后从第一服务器接收逻辑标识符;其中第一会话在会话中由客户端发送一条或多条命令的集合之后变为客户端不可用;并且其中所述请求至少部分地基于客户端在第一会话中完成先前的命令集之后接收到的逻辑标识符来识别命令集。
X6、如实施例X1所述的方法,其中所述一条或多条命令的集合是一条或多条命令的第一集合,其中用于输出的请求至少部分地基于在会话发送的多个命令集中的一条或多条命令的第一集合所特有的逻辑标识符来识别一条或多条命令的第一集合,其中标识符至少部分地基于在会话中发送的一条或多条命令的先前集合完成后才发送至客户端的指示,其中一条或多条命令的先前集合由客户端在会话中先于一条或多条命令的第一集合发送。
X7、如实施例X1所述的方法,其中用于输出的请求至少部分地基于包括先前在会话中发送至客户端的信息的逻辑标识符来识别一条或多条命令的所述集合,其中所述逻辑标识符唯一地识别出:
在会话发送的一条或多条命令的多个集合中由一条或多条命令的特定集合;以及
在多个服务器对数据库提供访问的多个会话中的特定会话,其中多个会话中的每一个会话同时最多被分配给一个服务器。
X8、如实施例X1所述的方法,进一步包括:
向客户端发送指示一条或多条命令的不同集合已交付的不同消息;
如果交付就在送往客户端的不同消息中附带一条或多条命令的不同集合中不同的逻辑标识符,其中不同的消息包括一条或多条命令的不同集合中不同的结果集合;
其中客户端请求至少部分地基于不同逻辑标识符中的特定逻辑标识符识别不同命令集中的特定命令集。
X9、如实施例X1所述的方法,其中所述会话是第一会话,其中用于输出的请求在第二会话中从客户端接收,并且其中所述响应在第二会话中发送,所述方法进一步包括响应于确定命令集中至少有一项事务尚未交付,通过阻止在第一会话中发送的一条或多条命令的集合内的至少一项事务在第一会话中完成而强行设定未交付状态以使这些命令不能在第一会话中交付。
X10、如实施例X9所述的方法,进一步包括执行第二会话中的至少一项事务,其中所述至少一项事务在第一会话和第二会话中最多交付一次。
X11、如实施例X1所述的方法,其中所述会话是第一会话,其中用于输出的请求在第二会话中从客户端接收,并且其中所述响应在第二会话中发送,进一步包括在第一会话中完成第一服务器操作,并且响应于更新存储信息以指示在一条或多条命令的集合中至少有一项另外的事务尚未交付,通过阻止这些事务不得在第一会话中交付来强行设定未交付状态以使第二会话能够完成这些命令;其中确定所识别的一条或多条命令的集合内至少有一项事务已交付且所识别的一条或多条命令的集合内至少还有一项另外的事务尚未交付应至少部分地基于存储信息。
X12、如实施例X11所述的方法,进一步包括:
响应于确定所识别的一条或多条命令的集合内至少有一项事务已交付且所识别的一条或多条命令的集合内至少还有一项另外的事务尚未交付,通过更新存储信息以指示在一条或多条命令的集合中至少有一项另外的事务已被阻止不得在第一会话中完成而在第一会话中阻止所识别的一条或多条命令的集合内至少一项另外的事务完成来强行设定未交付状态。
X13、一种方法,包括:
服务器在第二会话中从客户端接收请求,所述请求利用第一会话的逻辑标识符识别出由客户端在第一会话中发送的一条或多条命令的集合;其中所识别的一条或多条命令的集合如果在第一会话中已完成就促使实施:
交付事务的第一服务器操作;
服务器确定在所识别的一条或多条命令的集合中没有已交付的事务;并且
响应于请求和至少部分地基于确定命令集中没有已交付的事务,服务器通过阻止在第一会话中发送的所识别的一条或多条命令的集合内的任何事务完成而强行设定未交付状态以使未交付的输出被确保用于所识别的一条或多条命令的集合。
X14、如实施例X13所述的方法,进一步包括服务器在第二会话中促使完成一条或多条命令的集合。
X15、如实施例X13所述的方法,其中所述请求至少部分地基于客户端在第一会话中完成先前的命令集之后接收到的逻辑标识符来识别一条或多条命令的集合;其中在第一会话中交付所识别的一条或多条命令的集合需要服务器将存留关于识别命令集输出的存储信息作为交付第一会话的一部分;其中阻止在第一会话中发送的所识别的一条或多条命令的集合内的任何事务完成包括如果第一会话中的交付被阻止就在第一会话以外存留关于识别命令集输出的存储信息。
X16、一种方法,包括:
服务器在第二会话中从客户端接收请求,所述请求利用由客户端在第一会话中接收的逻辑标识符识别出由客户端在第一会话中发送的一条或多条命令的集合;其中所识别的一条或多条命令的集合如果在第一会话中已完成就促使实施:
交付事务的第一服务器操作,以及
向客户端发送所识别的一条或多条命令的集合已经跟生成的下一个逻辑标识符一起交付的指示的第二服务器操作,其中所识别的一条或多条命令的集合已交付的指示直到第一服务器操作已交付事务且完成之后才发送至客户端;
至少部分地基于所识别的一条或多条命令的集合输出的相关存储信息,服务器确定所识别的一条或多条命令的集合内的所有事务均已交付;即使在请求之前第二服务器操作并未向客户端报告所识别的一条或多条命令的集合已经交付且完成,服务器也向客户端发送对请求的响应以指示所识别的一条或多条命令的集合内的所有事务均已交付。
X17、一种或多种存储命令的非瞬时性计算机可读取介质,所述命令在由一个或多个处理器执行时促使实施如实施例X1所述的方法。
X18、一种或多种存储命令的非瞬时性计算机可读取介质,所述命令在由一个或多个处理器执行时促使实施如实施例X2所述的方法。
X18、一种或多种存储命令的非瞬时性计算机可读取介质,所述命令在由一个或多个处理器执行时促使实施如实施例X13所述的方法。
X20、一种或多种存储命令的非瞬时性计算机可读取介质,所述命令在由一个或多个处理器执行时促使实施如实施例X16所述的方法。
X21、如实施例X16所述的方法,其中在向客户端发送对请求的响应以指示所识别的一条或多条命令的集合内的所有事务均已交付之前,服务器确定所识别的一条或多条命令的集合如果在第一会话中交付那么是否会造成要将客户端所需的任何信息返回给客户端,并且如果答案为是,那么是否已经准备好将所需信息返回给客户端;其中向客户端发送对请求的响应以指示所识别的一条或多条命令的集合内的所有事务均已交付应响应于确定所识别的一条或多条命令的集合如果在第一会话中交付和完成则不会造成所需信息返回或尚未造成所需信息返回而执行。
X22、如实施例X16所述的方法,其中在向客户端发送对请求的响应以指示所识别的一条或多条命令的集合内的所有事务均已交付之前,服务器确定所识别的一条或多条命令的集合如果在第一会话中交付那么是否会造成第一会话中状态的明确改变,以及如果答案为是,那么状态的明确改变是否可以保存在第二会话中;其中向客户端发送对请求的响应以指示所识别的一条或多条命令的集合内的所有事务均已交付应响应于确定所识别的一条或多条命令的集合不会造成第一会话中状态的明确改变而执行。
在以上的说明书中,已经参照可以在不同实施方式中有所改变的多种具体细节内容介绍了本发明的实施例。因此说明书和附图应该以说明性而不是限制性的观点来看待。本发明专有和排他性的保护范围指示以及申请人所指的本发明保护范围的内容是由本申请以给出这些权利要求的具体形式而提出的权利要求集合的文字内容和等价范围,其中包括所有的后续补正。
如本文中所用的术语“第一”、“第二”、“第三”和“特定的”被作为命名惯例使用以区分彼此间不同的进程、命令、对象、设备或其他项目,从而使得在引入这些不同的项目之后能够进行引用。这些术语的使用并不意味着排序或时间安排。
相关申请的交叉引用
本申请涉及并要求2011年9月9日提交的申请号为13/229,641且发明名称为“Recovering Stateful Read-Only Database Sessions”的美国申请的优先权,因此通过引用并入其全部内容,就像在本文中完整阐述过一样。所以申请人拒绝放弃专利申请或其审查历史中主张的任何权利要求范围。
本申请涉及并在2012年4月16日提交的申请号为13/448,267且发明名称也是“用于数据库事务的幂等性(Idempotence For Database Transactions)”的美国专利申请,通过引用并入其全部内容,就像在本文中完整阐述过一样。
本申请还涉及:(1)2004年8月12日提交的发明名称为“Transparent MigrationOf Stateless Sessions Across Servers”的美国专利US7747754,通过引用并入其全部内容,就像在本文中完整阐述过一样;(2)2006年5月1日提交的发明名称为“DatabaseShutdown With Session Migration”的美国专利US7502824,通过引用并入其全部内容,就像在本文中完整阐述过一样;(3)2004年8月12日提交的发明名称为“Transparent SessionMigration Across Servers”的美国专利US7552218,通过引用并入其全部内容,就像在本文中完整阐述过一样;(4)2005年5月17日提交的发明名称为“Capturing And Re-CreatingThe 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”的美国专利申请,通过引用并入其全部内容,就像在本文中完整阐述过一样。
Claims (12)
1.一种方法,包括:
服务器在第二会话中从客户端接收请求,所述请求识别由所述客户端在第一会话中发送的命令集,其中所述命令集包括一个或多个事务;
所述服务器确定所述命令集中的所述一个或多个事务中的至少一个事务尚未交付;以及
至少部分地基于确定所述一个或多个事务中的所述至少一个事务尚未交付,所述服务器在所述第二会话中阻止所述第一会话中启动的所述至少一个事务完成以防止所述第一会话中启动的所述至少一个事务交付;
其中所述方法由一个或多个计算设备执行。
2.如权利要求1所述的方法,还包括在所述服务器阻止所述第一会话中启动的所述至少一个事务完成之后,所述服务器促使在所述第二会话中交付所述至少一个事务。
3.如权利要求1所述的方法,还包括:
在所述服务器阻止所述第一会话中启动的所述至少一个事务完成之后,所述服务器促使在所述第二会话中完成所述命令集;以及
响应于所述请求,向所述客户端发送所述命令集完成的指示;
其中所述阻止保证在包括所述第一会话和所述第二会话的至少两个会话中所述至少一个事务的单次执行。
4.如权利要求1所述的方法,其中所述请求通过指定在所述第一会话中由所述客户端接收到的逻辑标识符来识别所述命令集。
5.如权利要求1所述的方法,其中所述请求至少部分地基于在所述第一会话中完成先前的命令集之后由所述客户端接收到的逻辑标识符来识别所述命令集。
6.如权利要求1所述的方法,
其中所述命令集包括第一事务和第二事务;
其中所述服务器确定所述第一事务已交付并且所述第二事务尚未交付;
其中当所述第一事务已交付并且所述第二事务尚未交付时,构建中间会话状态;
其中所述服务器在所述第二会话中阻止所述至少一个事务完成包括阻止所述第一会话中启动的所述第二事务完成,以防止所述第一会话中启动的所述第二事务交付。
7.如权利要求6所述的方法,还包括在阻止所述第一会话中启动的所述第二事务完成之后,所述服务器促使在所述第二会话中交付所述第二事务。
8.如权利要求1所述的方法,
其中在所述第一会话中交付所述一个或多个事务中的至少一个事务将要求所述服务器在所述第一会话中存留关于所述命令集的一个或多个输出的存储信息;
其中阻止所述一个或多个事务中的至少一个事务完成包括在所述第一会话之外存留关于所述命令集的一个或多个输出的所述存储信息;
其中在所述第一会话之外存留的所述存储信息防止在所述第一会话中交付所述一个或多个事务中的所述至少一个事务。
9.如权利要求8所述的方法,其中关于所述命令集的一个或多个输出的所述存储信息包括关于所述命令集的所述一个或多个事务中的每个事务的输出的存储信息。
10.如权利要求1所述的方法,
其中所述命令集是来自所述客户端的单用户调用;
其中所述单用户调用如果在所述第一会话中完成将促使在所述第一会话中交付所述命令集的所述一个或多个事务的多项改变。
11.一种计算机系统,包括:
一个或多个处理器;以及
存储指令的一个或多个非暂态存储器,所述指令在由一个或多个处理器执行时使得如权利要求1至10中的任意一项所述的方法被实施。
12.一种存储指令的非暂态计算机可读介质,所述指令在由一个或多个处理器执行时使得如权利要求1至10中的任意一项所述的方法被实施。
Applications Claiming Priority (5)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
US13/229,641 | 2011-09-09 | ||
US13/229,641 US8549154B2 (en) | 2011-09-09 | 2011-09-09 | Recovering stateful read-only database sessions |
US13/448,258 | 2012-04-16 | ||
US13/448,258 US8984170B2 (en) | 2011-09-09 | 2012-04-16 | Idempotence for database transactions |
CN201280043616.6A CN103782574B (zh) | 2011-09-09 | 2012-09-07 | 用于数据库事务的幂等性 |
Related Parent Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN201280043616.6A Division CN103782574B (zh) | 2011-09-09 | 2012-09-07 | 用于数据库事务的幂等性 |
Publications (2)
Publication Number | Publication Date |
---|---|
CN107070919A true CN107070919A (zh) | 2017-08-18 |
CN107070919B CN107070919B (zh) | 2020-06-26 |
Family
ID=47172860
Family Applications (2)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN201280043616.6A Active CN103782574B (zh) | 2011-09-09 | 2012-09-07 | 用于数据库事务的幂等性 |
CN201710250782.8A Active CN107070919B (zh) | 2011-09-09 | 2012-09-07 | 用于数据库事务的幂等性 |
Family Applications Before (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN201280043616.6A Active CN103782574B (zh) | 2011-09-09 | 2012-09-07 | 用于数据库事务的幂等性 |
Country Status (4)
Country | Link |
---|---|
US (2) | US8984170B2 (zh) |
EP (2) | EP2754284B1 (zh) |
CN (2) | CN103782574B (zh) |
WO (1) | WO2013036871A1 (zh) |
Cited By (4)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN107580032A (zh) * | 2017-08-23 | 2018-01-12 | 阿里巴巴集团控股有限公司 | 数据处理方法、装置及设备 |
CN108279762A (zh) * | 2018-01-22 | 2018-07-13 | 北京计算机技术及应用研究所 | 基于硬件保护的事务处理方法 |
CN109815247A (zh) * | 2019-01-09 | 2019-05-28 | 金蝶软件(中国)有限公司 | 信息同步方法、装置、计算机设备和存储介质 |
CN111526184A (zh) * | 2020-04-07 | 2020-08-11 | 中国建设银行股份有限公司 | 业务审核的方法和装置 |
Families Citing this family (75)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US9047351B2 (en) | 2010-04-12 | 2015-06-02 | Sandisk Enterprise Ip Llc | Cluster of processing nodes with distributed global flash memory using commodity server technology |
US9164554B2 (en) | 2010-04-12 | 2015-10-20 | Sandisk Enterprise Ip Llc | Non-volatile solid-state storage system supporting high bandwidth and random access |
US8954385B2 (en) * | 2010-06-28 | 2015-02-10 | Sandisk Enterprise Ip Llc | Efficient recovery of transactional data stores |
US8874515B2 (en) | 2011-04-11 | 2014-10-28 | Sandisk Enterprise Ip Llc | Low level object version tracking using non-volatile memory write generations |
US8549154B2 (en) | 2011-09-09 | 2013-10-01 | Oracle International Corporation | Recovering stateful read-only database sessions |
US9600371B2 (en) | 2011-09-09 | 2017-03-21 | Oracle International Corporation | Preserving server-client session context |
US8725882B2 (en) | 2011-09-09 | 2014-05-13 | Oracle International Corporation | Masking database outages from clients and applications |
US8924346B2 (en) | 2011-09-09 | 2014-12-30 | Oracle International Corporation | Idempotence for database transactions |
US9135064B2 (en) | 2012-03-07 | 2015-09-15 | Sandisk Enterprise Ip Llc | Fine grained adaptive throttling of background processes |
US9477557B2 (en) | 2013-03-28 | 2016-10-25 | Microsoft Technology Licensing, Llc | Transaction processing using torn write detection |
US9734187B2 (en) * | 2013-04-03 | 2017-08-15 | Salesforce.Com, Inc. | Atomic transactions in a NOSQL database |
US9948726B2 (en) * | 2013-07-01 | 2018-04-17 | Avaya Inc. | Reconstruction of states on controller failover |
US9342351B1 (en) * | 2013-11-01 | 2016-05-17 | Bmc Software, Inc. | Systems and methods for efficient DB2 outage operations |
CN104793988B (zh) * | 2014-01-20 | 2019-01-22 | 阿里巴巴集团控股有限公司 | 跨数据库分布式事务的实现方法和装置 |
US9961011B2 (en) | 2014-01-21 | 2018-05-01 | Oracle International Corporation | System and method for supporting multi-tenancy in an application server, cloud, or other environment |
WO2015140931A1 (ja) * | 2014-03-18 | 2015-09-24 | 株式会社 東芝 | トライアル領域を備えた階層化ストレージシステム、ストレージコントローラ及びプログラム |
US10657465B2 (en) * | 2014-03-24 | 2020-05-19 | Amadeus S.A.S. | Double-booking prevention |
ES2835881T3 (es) * | 2014-03-24 | 2021-06-23 | Amadeus Sas | Prevención de doble procesamiento |
US10152605B2 (en) * | 2014-05-21 | 2018-12-11 | Siddharth Shetye | Systems and methods for front-end and back-end data security protocols |
KR102437664B1 (ko) * | 2014-09-26 | 2022-08-29 | 오라클 인터내셔날 코포레이션 | 멀티테넌트 어플리케이션 서버 환경에서 트랜잭션 복구를 위한 시스템 및 방법 |
CN105740258B (zh) * | 2014-12-09 | 2019-01-04 | 阿里巴巴集团控股有限公司 | 基于幂等号校验的业务处理方法及装置 |
US9953053B2 (en) * | 2014-12-18 | 2018-04-24 | International Business Machines Corporation | Reliability improvement of distributed transaction processing optimizations based on connection status |
US10318520B2 (en) * | 2015-03-31 | 2019-06-11 | Oracle International Corporation | System and method for reducing communications overhead in a distributed transactions environment by modifying implementation of the transaction end function |
US9892160B2 (en) | 2015-04-07 | 2018-02-13 | International Business Machines Corporation | Database statistics based on transaction state |
US10255336B2 (en) | 2015-05-07 | 2019-04-09 | Datometry, Inc. | Method and system for transparent interoperability between applications and data management systems |
US11294864B2 (en) * | 2015-05-19 | 2022-04-05 | Vmware, Inc. | Distributed transactions with redo-only write-ahead log |
US11301457B2 (en) | 2015-06-29 | 2022-04-12 | Microsoft Technology Licensing, Llc | Transactional database layer above a distributed key/value store |
US10594779B2 (en) * | 2015-08-27 | 2020-03-17 | Datometry, Inc. | Method and system for workload management for data management systems |
CN105205175B (zh) * | 2015-10-15 | 2019-01-18 | 北京农信互联科技集团有限公司 | 分布式数据库集群的数据操作方法及系统 |
US9838505B2 (en) * | 2015-12-11 | 2017-12-05 | Sap Se | Application based context pooling |
US11295293B2 (en) * | 2016-01-07 | 2022-04-05 | Worldpay, Llc | Point of interaction device emulation for payment transaction simulation |
US10339127B2 (en) | 2016-01-28 | 2019-07-02 | Oracle International Corporation | Guaranteed commit outcome in a distributed transaction processing system |
US10417038B2 (en) | 2016-02-18 | 2019-09-17 | Red Hat, Inc. | Batched commit in distributed transactions |
US10204130B2 (en) | 2016-03-23 | 2019-02-12 | International Business Machines Corporation | Transactional table truncation for concurrent transactions |
CN105915627A (zh) * | 2016-05-30 | 2016-08-31 | 北京小米移动软件有限公司 | 业务请求处理方法及装置 |
US10552442B1 (en) * | 2016-08-29 | 2020-02-04 | Amazon Technologies, Inc. | Stateful database application programming interface |
US10412190B1 (en) * | 2016-09-12 | 2019-09-10 | Amazon Technologies, Inc. | Device multi-step state transitions |
CN107844490B (zh) * | 2016-09-19 | 2020-12-08 | 华为技术有限公司 | 一种数据库的分库方法及装置 |
US10496665B2 (en) * | 2016-11-17 | 2019-12-03 | Sap Se | Database system incorporating document store |
US10678812B2 (en) * | 2016-11-17 | 2020-06-09 | Sap Se | Asynchronous database transaction handling |
US10565187B2 (en) * | 2016-11-17 | 2020-02-18 | Sap Se | Management of transactions spanning different database types |
US10558488B2 (en) * | 2017-01-06 | 2020-02-11 | International Business Machines Corporation | Sharing transaction contexts in an optimized colocation of java and non-java language applications |
CN106850820A (zh) * | 2017-02-20 | 2017-06-13 | 济南浪潮高新科技投资发展有限公司 | 数据存储方法、客户端、服务端、可读介质及存储控制器 |
US11170023B2 (en) * | 2017-02-28 | 2021-11-09 | Sap Se | Replay of redo log records in persistency or main memory of database systems |
US10956369B1 (en) * | 2017-04-06 | 2021-03-23 | Amazon Technologies, Inc. | Data aggregations in a distributed environment |
US10635577B2 (en) | 2017-04-07 | 2020-04-28 | International Business Machines Corporation | Integration times in a continuous integration environment based on statistical modeling |
CN109101341B (zh) * | 2017-06-21 | 2022-02-22 | 阿里巴巴集团控股有限公司 | 分布式锁的分配方法及设备 |
US10579613B2 (en) * | 2017-08-08 | 2020-03-03 | International Business Machines Corporation | Database recovery using persistent address spaces |
US12007941B2 (en) | 2017-09-29 | 2024-06-11 | Oracle International Corporation | Session state tracking |
US10866963B2 (en) | 2017-12-28 | 2020-12-15 | Dropbox, Inc. | File system authentication |
CN108805569A (zh) * | 2018-05-29 | 2018-11-13 | 阿里巴巴集团控股有限公司 | 基于区块链的交易处理方法及装置、电子设备 |
CN108764870B (zh) | 2018-05-29 | 2020-07-07 | 阿里巴巴集团控股有限公司 | 基于区块链的交易处理方法及装置、电子设备 |
US11061884B2 (en) | 2018-10-17 | 2021-07-13 | Oracle International Corporation | Method and system to accelerate transaction commit using non-volatile memory |
US11294869B1 (en) | 2018-12-19 | 2022-04-05 | Datometry, Inc. | Expressing complexity of migration to a database candidate |
US11436213B1 (en) | 2018-12-19 | 2022-09-06 | Datometry, Inc. | Analysis of database query logs |
US11615062B1 (en) | 2018-12-20 | 2023-03-28 | Datometry, Inc. | Emulation of database catalog for migration to a different database |
CN110191165B (zh) * | 2019-05-20 | 2023-05-12 | 深圳前海微众银行股份有限公司 | 一种处理代码执行请求的方法及装置 |
CN114880698B (zh) * | 2019-06-29 | 2022-11-25 | 华为云计算技术有限公司 | 数据库访问方法和装置、计算设备和计算机程序产品 |
US11936739B2 (en) * | 2019-09-12 | 2024-03-19 | Oracle International Corporation | Automated reset of session state |
US11687507B2 (en) | 2019-09-12 | 2023-06-27 | Oracle International Corporation | Termination of database sessions for planned failover |
CN110569257B (zh) * | 2019-09-16 | 2022-04-01 | 上海达梦数据库有限公司 | 数据处理方法、相应装置、设备及存储介质 |
US11652892B2 (en) | 2019-09-30 | 2023-05-16 | Oracle International Corporation | Automatic connection load balancing between instances of a cluster |
CN112749175B (zh) * | 2019-10-30 | 2023-10-03 | 网联清算有限公司 | 交易处理方法和装置以及电子设备和介质 |
CN111241112B (zh) * | 2019-12-27 | 2023-05-23 | 山大地纬软件股份有限公司 | 一种保证幂等的微服务调用监管系统及方法 |
US11636071B2 (en) * | 2020-01-10 | 2023-04-25 | Salesforce.Com, Inc. | Database replication error recovery based on supervised learning |
FR3110723B1 (fr) * | 2020-05-21 | 2022-05-13 | Amadeus | Mise à jour de session de base de données asynchrone |
CN113704222A (zh) * | 2020-05-21 | 2021-11-26 | 北京沃东天骏信息技术有限公司 | 一种处理业务请求的方法和装置 |
US11409618B2 (en) * | 2020-09-14 | 2022-08-09 | International Business Machines Corporation | Transaction recovery |
US11461315B2 (en) * | 2020-12-03 | 2022-10-04 | International Business Machines Corporation | Batch job performance improvement in active-active architecture |
US12061526B2 (en) | 2021-06-08 | 2024-08-13 | Salesforce, Inc. | History information in director-based database system for transactional consistency |
US11822535B2 (en) | 2021-06-08 | 2023-11-21 | Salesforce, Inc. | Director-based database system for transactional consistency |
US11989051B2 (en) | 2021-06-08 | 2024-05-21 | Salesforce, Inc. | Time alignment in director-based database system for transactional consistency |
CN113886481B (zh) * | 2021-12-06 | 2022-03-04 | 北京宇信科技集团股份有限公司 | 一种数据库访问方法和系统 |
US12093139B2 (en) * | 2021-12-16 | 2024-09-17 | International Business Machines Corporation | Rolling back a database transaction |
US11526491B1 (en) * | 2022-02-21 | 2022-12-13 | Clari Inc. | Method and system for collecting data from data sources with commit lag to maintain data consistency in a data store |
Citations (4)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US6442552B1 (en) * | 2000-06-30 | 2002-08-27 | Hewlett-Packard Company | Method and apparatus for implementing three tier client asynchronous transparency |
CN101185076A (zh) * | 2005-03-31 | 2008-05-21 | 瑞士银行股份有限公司 | 用于使第二数据库与第一数据库同步的计算机网络系统及相应过程 |
US20090182787A1 (en) * | 2008-01-11 | 2009-07-16 | Paul Parkinson | Recovery Administration of Global Transaction Participants |
CN101853186A (zh) * | 2008-12-31 | 2010-10-06 | Sap股份公司 | 分布式事务恢复系统和方法 |
Family Cites Families (51)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US6041357A (en) | 1997-02-06 | 2000-03-21 | Electric Classified, Inc. | Common session token system and protocol |
US6490610B1 (en) | 1997-05-30 | 2002-12-03 | Oracle Corporation | Automatic failover for clients accessing a resource through a server |
US6801914B2 (en) * | 1999-03-15 | 2004-10-05 | Microsoft Corporation | Persistent client-server database sessions |
US6732175B1 (en) | 2000-04-13 | 2004-05-04 | Intel Corporation | Network apparatus for switching based on content of application data |
US7539746B2 (en) * | 2001-02-01 | 2009-05-26 | Emc Corporation | Highly available transaction failure detection and recovery for electronic commerce transactions |
US7849173B1 (en) | 2001-12-31 | 2010-12-07 | Christopher Uhlik | System for on-demand access to local area networks |
US7949702B2 (en) * | 2002-01-09 | 2011-05-24 | International Business Machines Corporation | Method and apparatus for synchronizing cookies across multiple client machines |
US20040015600A1 (en) | 2002-02-21 | 2004-01-22 | Ashutosh Tiwary | Workload post-processing and parameterization for a system for performance testing of N-tiered computer systems using recording and playback of workloads |
US6963996B2 (en) * | 2002-04-30 | 2005-11-08 | Intel Corporation | Session error recovery |
US7627693B2 (en) | 2002-06-11 | 2009-12-01 | Pandya Ashish A | IP storage processor and engine therefor using RDMA |
US7631107B2 (en) | 2002-06-11 | 2009-12-08 | Pandya Ashish A | Runtime adaptable protocol processor |
WO2004055674A1 (ja) | 2002-12-18 | 2004-07-01 | Fujitsu Limited | 分散トランザクション処理装置、分散トランザクション処理プログラム、分散トランザクション処理方法および分散トランザクション処理システム |
US7743083B2 (en) | 2003-04-24 | 2010-06-22 | Oracle America, Inc. | Common transaction manager interface for local and global transactions |
US7346905B2 (en) * | 2003-06-10 | 2008-03-18 | International Business Machines Corporation | Apparatus and method for maintaining resource integrity without a unified transaction manager in a software environment |
CN100547583C (zh) * | 2003-08-14 | 2009-10-07 | 甲骨文国际公司 | 数据库的自动和动态提供的方法 |
US7340452B2 (en) | 2003-12-16 | 2008-03-04 | Oracle International Corporation | Parallel single cursor model on multiple-server configurations |
US20050186975A1 (en) | 2004-02-10 | 2005-08-25 | Yach David P. | Apparatus, and associated method, for facilitating initiation of synchronization of database copies connected by way of a radio air interface |
US7758892B1 (en) | 2004-05-20 | 2010-07-20 | Boston Scientific Scimed, Inc. | Medical devices having multiple layers |
US7415470B2 (en) | 2004-08-12 | 2008-08-19 | Oracle International Corporation | Capturing and re-creating the state of a queue when migrating a session |
US7502824B2 (en) | 2004-08-12 | 2009-03-10 | Oracle International Corporation | Database shutdown with session migration |
US7587400B2 (en) | 2004-08-12 | 2009-09-08 | Oracle International Corporation | Suspending a result set and continuing from a suspended result set for transparent session migration |
US7543069B2 (en) * | 2004-10-18 | 2009-06-02 | International Business Machines Corporation | Dynamically updating session state affinity |
US7761435B2 (en) | 2005-04-29 | 2010-07-20 | Sap Ag | External persistence of session state information |
US7853698B2 (en) | 2005-04-29 | 2010-12-14 | Sap Ag | Internal persistence of session state information |
US7430559B2 (en) * | 2005-09-21 | 2008-09-30 | Microsoft Corporation | Generalized idempotent requests |
US7996837B2 (en) | 2006-05-03 | 2011-08-09 | Oracle International Corporation | Recovery mechanism for transactions |
US7877373B2 (en) | 2006-06-30 | 2011-01-25 | Oracle International Corporation | Executing alternative plans for a SQL statement |
US7890458B2 (en) | 2006-10-20 | 2011-02-15 | Oracle International Corporation | Capturing database workload while preserving original transactional and concurrency characteristics for replay |
US7634512B2 (en) | 2006-10-20 | 2009-12-15 | Oracle International Corporation | Migrating temporary data of a session |
US7890457B2 (en) | 2006-10-20 | 2011-02-15 | Oracle International Corporation | Transactionally consistent database workload replay |
US20080098003A1 (en) | 2006-10-20 | 2008-04-24 | Oracle International Corporation | Database workload replay remapping infrastructure |
US7984015B2 (en) | 2006-10-20 | 2011-07-19 | Oracle International Corporation | Database workload capture and replay architecture |
US8024299B2 (en) | 2006-10-20 | 2011-09-20 | Oracle International Corporation | Client-driven functionally equivalent database replay |
US8392483B2 (en) * | 2006-11-20 | 2013-03-05 | Matrikon Inc. | Ontological database design |
US8768890B2 (en) | 2007-03-14 | 2014-07-01 | Microsoft Corporation | Delaying database writes for database consistency |
US7882173B2 (en) * | 2008-06-30 | 2011-02-01 | International Business Machines Corporation | Interactive remote command execution over a stateless client/server network protocol |
US8433680B2 (en) | 2008-07-01 | 2013-04-30 | Oracle International Corporation | Capturing and restoring database session state |
US20100030818A1 (en) | 2008-07-31 | 2010-02-04 | Yahoo! Inc. | System and method for applying once a transaction delivered in a message published asynchronously in a distributed database |
US8224850B2 (en) * | 2008-08-13 | 2012-07-17 | Motorola Mobility, Inc. | Method and system for determining users that satisfy desired conditions |
US8296358B2 (en) * | 2009-05-14 | 2012-10-23 | Hewlett-Packard Development Company, L.P. | Method and system for journaling data updates in a distributed file system |
US20100318394A1 (en) * | 2009-06-15 | 2010-12-16 | Microsoft Corporation | Executing transactions as an atomic unit |
US8556724B2 (en) | 2009-09-30 | 2013-10-15 | Zynga Inc. | Apparatuses, methods and systems for an online game manager |
EP2363806A1 (en) | 2010-03-03 | 2011-09-07 | Software AG | Connection handler and method for providing applications with heterogeneous connection objects |
US8584124B2 (en) * | 2010-04-20 | 2013-11-12 | Salesforce.Com, Inc. | Methods and systems for batch processing in an on-demand service environment |
US8442962B2 (en) | 2010-12-28 | 2013-05-14 | Sap Ag | Distributed transaction management using two-phase commit optimization |
US8868514B2 (en) * | 2011-01-07 | 2014-10-21 | Microsoft Corporation | Transaction support for distributed data |
US8924346B2 (en) | 2011-09-09 | 2014-12-30 | Oracle International Corporation | Idempotence for database transactions |
US8725882B2 (en) | 2011-09-09 | 2014-05-13 | Oracle International Corporation | Masking database outages from clients and applications |
US8549154B2 (en) | 2011-09-09 | 2013-10-01 | Oracle International Corporation | Recovering stateful read-only database sessions |
US9600371B2 (en) | 2011-09-09 | 2017-03-21 | Oracle International Corporation | Preserving server-client session context |
US10430391B2 (en) | 2012-09-28 | 2019-10-01 | Oracle International Corporation | Techniques for activity tracking, data classification, and in database archiving |
-
2012
- 2012-04-16 US US13/448,258 patent/US8984170B2/en active Active
- 2012-09-07 EP EP12784360.5A patent/EP2754284B1/en active Active
- 2012-09-07 WO PCT/US2012/054311 patent/WO2013036871A1/en active Search and Examination
- 2012-09-07 CN CN201280043616.6A patent/CN103782574B/zh active Active
- 2012-09-07 EP EP15161374.2A patent/EP2928160B1/en active Active
- 2012-09-07 CN CN201710250782.8A patent/CN107070919B/zh active Active
-
2014
- 2014-12-31 US US14/587,570 patent/US10250693B2/en active Active
Patent Citations (4)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US6442552B1 (en) * | 2000-06-30 | 2002-08-27 | Hewlett-Packard Company | Method and apparatus for implementing three tier client asynchronous transparency |
CN101185076A (zh) * | 2005-03-31 | 2008-05-21 | 瑞士银行股份有限公司 | 用于使第二数据库与第一数据库同步的计算机网络系统及相应过程 |
US20090182787A1 (en) * | 2008-01-11 | 2009-07-16 | Paul Parkinson | Recovery Administration of Global Transaction Participants |
CN101853186A (zh) * | 2008-12-31 | 2010-10-06 | Sap股份公司 | 分布式事务恢复系统和方法 |
Cited By (6)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN107580032A (zh) * | 2017-08-23 | 2018-01-12 | 阿里巴巴集团控股有限公司 | 数据处理方法、装置及设备 |
CN108279762A (zh) * | 2018-01-22 | 2018-07-13 | 北京计算机技术及应用研究所 | 基于硬件保护的事务处理方法 |
CN109815247A (zh) * | 2019-01-09 | 2019-05-28 | 金蝶软件(中国)有限公司 | 信息同步方法、装置、计算机设备和存储介质 |
CN109815247B (zh) * | 2019-01-09 | 2021-05-07 | 金蝶软件(中国)有限公司 | 信息同步方法、装置、计算机设备和存储介质 |
CN111526184A (zh) * | 2020-04-07 | 2020-08-11 | 中国建设银行股份有限公司 | 业务审核的方法和装置 |
CN111526184B (zh) * | 2020-04-07 | 2022-07-29 | 中国建设银行股份有限公司 | 业务审核的方法和装置 |
Also Published As
Publication number | Publication date |
---|---|
EP2928160B1 (en) | 2017-05-31 |
CN103782574B (zh) | 2017-05-10 |
US10250693B2 (en) | 2019-04-02 |
EP2928160A1 (en) | 2015-10-07 |
US20130066948A1 (en) | 2013-03-14 |
US8984170B2 (en) | 2015-03-17 |
WO2013036871A1 (en) | 2013-03-14 |
CN103782574A (zh) | 2014-05-07 |
CN107070919B (zh) | 2020-06-26 |
EP2754284A1 (en) | 2014-07-16 |
US20150172390A1 (en) | 2015-06-18 |
EP2754284B1 (en) | 2015-04-15 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
CN103782574B (zh) | 用于数据库事务的幂等性 | |
CN108459919B (zh) | 一种分布式事务处理方法及装置 | |
JP7142152B2 (ja) | トランザクション処理方法、装置、機器並びにコンピュータプログラム | |
CN103782573B (zh) | 对客户端和应用掩盖服务器停运 | |
US8924346B2 (en) | Idempotence for database transactions | |
US10942823B2 (en) | Transaction processing system, recovery subsystem and method for operating a recovery subsystem | |
US9569473B1 (en) | Method of controlling whether an uncompleted transaction applied against a database goes forward using either synchronous or asynchronous replication, or using either encrypted replication or unencrypted replication | |
US9317372B1 (en) | Dynamic membership management in a distributed system | |
US8676635B2 (en) | Method and system for managing transactions | |
US10296759B1 (en) | Method of controlling whether an uncompleted transaction applied against a database goes forward or is aborted, and for modifying the uncompleted transaction so that it can go forward | |
US10176243B1 (en) | Method and apparatus for logging non-durable attributes of an uncompleted transaction so as to make such attributes durable | |
Schwarz | JAP transaction processing failure scenarios | |
Design | HP Reliable Transaction Router Application Design Guide |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
PB01 | Publication | ||
PB01 | Publication | ||
SE01 | Entry into force of request for substantive examination | ||
SE01 | Entry into force of request for substantive examination | ||
GR01 | Patent grant | ||
GR01 | Patent grant |