用于數(shù)據(jù)庫(kù)事務(wù)的冪等性的制作方法
【專利摘要】提供了一種用于管理從客戶端發(fā)送至服務(wù)器以供執(zhí)行的事務(wù)性命令集的方法、機(jī)器和計(jì)算機(jī)可讀取介質(zhì)。第一服務(wù)器向客戶端報(bào)告識(shí)別事務(wù)性命令集的邏輯標(biāo)識(shí)符。第一服務(wù)器交付用于指示已交付集合的命令集相關(guān)信息。第二服務(wù)器基于客戶端已經(jīng)收到的邏輯標(biāo)識(shí)符從客戶端接收識(shí)別所述集合的請(qǐng)求。第二服務(wù)器確定請(qǐng)求在相應(yīng)的對(duì)話中是否識(shí)別出接收用于執(zhí)行的最新集合以及集合中是否存在尚未交付的任何事務(wù)。如果還有任何事務(wù)尚未交付,那么第二服務(wù)器就通過(guò)阻止第一會(huì)話中發(fā)布的所識(shí)別集合的完成來(lái)強(qiáng)行設(shè)定所識(shí)別集合的未交付狀態(tài)。所識(shí)別集合可以隨后無(wú)重復(fù)風(fēng)險(xiǎn)地在第二會(huì)話中執(zhí)行。
【專利說(shuō)明】用于數(shù)據(jù)庫(kù)事務(wù)的冪等性
[0001]相關(guān)申請(qǐng)的交叉引用
[0002]本申請(qǐng)涉及并要求2011年9月9日提交的申請(qǐng)?zhí)枮?3/229,641且發(fā)明名稱為“Recovering Stateful Read-Only Database Sessions”的美國(guó)申請(qǐng)的優(yōu)先權(quán),因此通過(guò)引用并入其全部?jī)?nèi)容,就像在本文中完整闡述過(guò)一樣。所以 申請(qǐng)人:拒絕放棄專利申請(qǐng)或其審查歷史中主張的任何權(quán)利要求范圍。
[0003]本申請(qǐng)涉及并在2012年4月16日提交的申請(qǐng)?zhí)枮?3/448,267且發(fā)明名稱也是“用于數(shù)據(jù)庫(kù)事務(wù)的冪等性(Idempotence For Database Transactions) ”的美國(guó)專利申請(qǐng),通過(guò)引用并入其全部?jī)?nèi)容,就像在本文中完整闡述過(guò)一樣。
[0004]本申請(qǐng)還涉及:(I) 2004年8月12日提交的發(fā)明名稱為“Transparent MigrationOf Stateless Sessions Across Servers” 的美國(guó)專利 US7747754,通過(guò)引用并入其全部?jī)?nèi)容,就像在本文中完整闡述過(guò)一樣;(2) 2006年5月I日提交的發(fā)明名稱為“DatabaseShutdown With Session Migration”的美國(guó)專利US7502824,通過(guò)引用并入其全部?jī)?nèi)容,就像在本文中完整闡述過(guò)一樣;(3)2004年8月12日提交的發(fā)明名稱為“TransparentSession Migration Across Servers”的美國(guó)專利US7552218,通過(guò)引用并入其全部?jī)?nèi)容,就像在本文中完整闡述過(guò)一樣;(4) 2005年5月17日提交的發(fā)明名稱為“Capturing AndRe-Creating The State Of A Queue When Migrating A Session”的美國(guó)專利US7415470,通過(guò)引用并入其全部?jī)?nèi)容,就像在本文中完整闡述過(guò)一樣;(5)2007年4月4日提交的發(fā)明名稱為“Migrating Temporary Data Of A Session” 的美國(guó)專利 US7634512,通過(guò)引用并入其全部?jī)?nèi)容,就像在本文中完整闡述過(guò)一樣;(6)2011年3月30日提交的申請(qǐng)?zhí)枮?3/076,313 且發(fā)明名稱為 “Application Workload Capture And Replay System” 的美國(guó)專利申請(qǐng),通過(guò)引用并入其全部?jī)?nèi)容,就像在本文中完整闡述過(guò)一樣。
【技術(shù)領(lǐng)域】
[0005]【技術(shù)領(lǐng)域】涉及管理從客戶端發(fā)送至服務(wù)器以供執(zhí)行的事務(wù)性命令集。
【背景技術(shù)】
[0006]服務(wù)器和客戶端
[0007]服務(wù)器是一種為一個(gè)或多個(gè)客戶端提供服務(wù)的操作軟件過(guò)程。服務(wù)器可以是操作用于為客戶端提供服務(wù)的相關(guān)軟件的若干不同服務(wù)器實(shí)例構(gòu)成的服務(wù)器實(shí)例(serverinstance)??蛻舳送ㄟ^(guò)服務(wù)器連接跟服務(wù)器通信。具體地,客戶端向服務(wù)器發(fā)送命令,而服務(wù)器執(zhí)行命令并可選地向客戶端送回結(jié)果。如本文中所用的服務(wù)器“操作”是指由服務(wù)器采用以執(zhí)行一條或多條客戶端命令的函數(shù)、過(guò)程或其他動(dòng)作。單條命令可以觸發(fā)多項(xiàng)服務(wù)器操作或者也可以對(duì)應(yīng)于單項(xiàng)服務(wù)器操作。例如,某些命令可以請(qǐng)求服務(wù)器除了執(zhí)行數(shù)據(jù)操作函數(shù)以外還要返回結(jié)果。另一些命令可以僅請(qǐng)求確認(rèn)數(shù)據(jù)操作命令得到執(zhí)行或者也可以不請(qǐng)求任何響應(yīng)。
[0008]客戶端可以要求執(zhí)行在請(qǐng)求中明確的命令集。作為響應(yīng),服務(wù)器可以執(zhí)行命令集并向客戶端確認(rèn)命令集已執(zhí)行。例如,服務(wù)器可以向客戶端提供結(jié)果或者可以僅提供命令集已執(zhí)行的指示。服務(wù)器和客戶端之間的連接可以隨時(shí)地、按計(jì)劃或不按計(jì)劃地變?yōu)椴豢捎?。例如,服?wù)器可能出錯(cuò),或者支持服務(wù)器和客戶端之間連接的網(wǎng)絡(luò)設(shè)備或其他源也可能出錯(cuò)。如果服務(wù)器和客戶端之間的連接在服務(wù)器響應(yīng)命令集之前就已變?yōu)椴豢捎?,那么客戶端就無(wú)法確定是否已經(jīng)完成了命令集。
[0009]數(shù)據(jù)庫(kù)服務(wù)器和數(shù)據(jù)庫(kù)應(yīng)用程序在本文中被提供分別作為服務(wù)器和客戶端的示例。但是,本文介紹的各種技術(shù)可以應(yīng)用于任何服務(wù)器-客戶端系統(tǒng)。
[0010]數(shù)據(jù)庫(kù)實(shí)例
[0011]數(shù)據(jù)庫(kù)包括存儲(chǔ)在一種或多種存儲(chǔ)設(shè)備例如硬盤、隨機(jī)存取記憶棒、存儲(chǔ)集群或云存儲(chǔ)系統(tǒng)內(nèi)的數(shù)據(jù)和元數(shù)據(jù)。這樣的數(shù)據(jù)和元數(shù)據(jù)可以根據(jù)例如關(guān)系和/或?qū)ο?關(guān)系數(shù)據(jù)庫(kù)結(jié)構(gòu)而按邏輯存儲(chǔ)在數(shù)據(jù)庫(kù)內(nèi)。數(shù)據(jù)庫(kù)應(yīng)用程序通過(guò)向數(shù)據(jù)庫(kù)實(shí)例提交命令促使數(shù)據(jù)庫(kù)實(shí)例對(duì)存儲(chǔ)在數(shù)據(jù)庫(kù)內(nèi)的數(shù)據(jù)執(zhí)行操作而跟數(shù)據(jù)庫(kù)服務(wù)器的實(shí)例(“數(shù)據(jù)庫(kù)實(shí)例”)交互。數(shù)據(jù)庫(kù)命令是用于訪問(wèn)或修改數(shù)據(jù)庫(kù)中數(shù)據(jù)的請(qǐng)求。命令可以促使數(shù)據(jù)庫(kù)實(shí)例對(duì)數(shù)據(jù)庫(kù)內(nèi)的數(shù)據(jù)執(zhí)行操作和/或從數(shù)據(jù)庫(kù)中返回?cái)?shù)據(jù)。
[0012]在多節(jié)點(diǎn)數(shù)據(jù)庫(kù)系統(tǒng)中,數(shù)據(jù)庫(kù)可以通過(guò)多個(gè)數(shù)據(jù)庫(kù)實(shí)例提供服務(wù),并且每一個(gè)數(shù)據(jù)庫(kù)實(shí)例都可以被設(shè)置用于訪問(wèn)全部或部分的數(shù)據(jù)庫(kù)。服務(wù)器實(shí)例是集成的軟件組件例如在一種或多種計(jì)算設(shè)備上運(yùn)行的進(jìn)程以及分配的用于在處理器上運(yùn)行集成軟件組件的計(jì)算資源例如內(nèi)存、存儲(chǔ)器或處理器周期的組合。數(shù)據(jù)庫(kù)實(shí)例是集成的軟件組件以及分配的用于訪問(wèn)、修改或以其他方式使用數(shù)據(jù)庫(kù)的計(jì)算資源的組合。數(shù)據(jù)庫(kù)實(shí)例可以分組為調(diào)用邏輯域的服務(wù)。多個(gè)數(shù)據(jù)庫(kù)實(shí)例可以被安裝或配置在單臺(tái)機(jī)器或分離的多臺(tái)機(jī)器上。在處理數(shù)據(jù)庫(kù)命令時(shí),數(shù)據(jù)庫(kù)實(shí)例可以訪問(wèn)數(shù)據(jù)庫(kù)或數(shù)據(jù)庫(kù)中的信息緩存。在一個(gè)示例中,數(shù)據(jù)庫(kù)被存儲(chǔ)在非易失性存儲(chǔ)器內(nèi),并且緩存被存儲(chǔ)在易失性存儲(chǔ)器內(nèi)。
[0013]在多個(gè)數(shù)據(jù)庫(kù)會(huì)話共享對(duì)相同數(shù)據(jù)的訪問(wèn)時(shí),會(huì)話中執(zhí)行的用戶命令可以在一部分?jǐn)?shù)據(jù)庫(kù)被服務(wù)于該會(huì)話的數(shù)據(jù)庫(kù)實(shí)例使用時(shí)鎖定這部分?jǐn)?shù)據(jù)庫(kù)。例如,用戶會(huì)話可以鎖定用于排他性的讀和/或?qū)懺L問(wèn)的部分,并且在所述部分已鎖定時(shí)其他的用戶會(huì)話被禁止訪問(wèn)和/或修改所述部分。用戶會(huì)話在數(shù)據(jù)庫(kù)實(shí)例完成對(duì)所述數(shù)據(jù)庫(kù)部分的訪問(wèn)和/或修改之后再釋放鎖定。在鎖定被釋放后,其他的實(shí)例即可訪問(wèn)和/或修改所述部分或者獲得對(duì)所述部分的鎖定。
[0014]數(shù)據(jù)庫(kù)命令可以用跟數(shù)據(jù)庫(kù)實(shí)例所支持的數(shù)據(jù)庫(kù)語(yǔ)言相符的數(shù)據(jù)庫(kù)語(yǔ)句的形式提交給數(shù)據(jù)庫(kù)實(shí)例。被多種數(shù)據(jù)庫(kù)實(shí)例支持的數(shù)據(jù)庫(kù)語(yǔ)言的一個(gè)非限制性示例是調(diào)用數(shù)據(jù)操作語(yǔ)言(“dml”)的結(jié)構(gòu)化查詢語(yǔ)言(“sql”),包括例如像Oracle?這樣的數(shù)據(jù)
庫(kù)服務(wù)器(譬如Oracle⑩Databasellg)所支持的專用形式的SQL。SQL數(shù)據(jù)定義語(yǔ)言
(“DDL”)指令被發(fā)送給數(shù)據(jù)庫(kù)服務(wù)器以創(chuàng)建或配置數(shù)據(jù)庫(kù)對(duì)象例如表、視圖或復(fù)雜類型。盡管SQL作為一個(gè)示例而被提及,但是還有很多其他的示例性數(shù)據(jù)庫(kù)語(yǔ)言和用于數(shù)據(jù)庫(kù)的開放接口,其中任何一種都可以結(jié)合本文所述的技術(shù)使用。
[0015]過(guò)程化語(yǔ)言/結(jié)構(gòu)化查詢語(yǔ)言(“PL/SQL”)通過(guò)提供在過(guò)程化語(yǔ)言中獲得的結(jié)構(gòu)來(lái)擴(kuò)展SQL,由此得到比標(biāo)準(zhǔn)SQL更加強(qiáng)大的結(jié)構(gòu)化語(yǔ)言。PL/SQL命令被組織為由變量聲明、包括過(guò)程和SQL命令的子命令以及異常處理命令構(gòu)成的模塊。PL/SQL命令可以被發(fā)送至數(shù)據(jù)庫(kù)服務(wù)器以在執(zhí)行PL/SQL命令時(shí)促使數(shù)據(jù)庫(kù)服務(wù)器執(zhí)行各種動(dòng)作。數(shù)據(jù)庫(kù)服務(wù)器還可以接收和執(zhí)行基于Java的命令、遠(yuǎn)程過(guò)程調(diào)用命令或者跟其他編程語(yǔ)言或結(jié)構(gòu)相符的命令。
[0016]可以在單次請(qǐng)求中將多條數(shù)據(jù)庫(kù)命令從數(shù)據(jù)庫(kù)客戶端發(fā)送至數(shù)據(jù)庫(kù)實(shí)例以完成工作。數(shù)據(jù)庫(kù)命令可以由數(shù)據(jù)庫(kù)實(shí)例處理,并且數(shù)據(jù)庫(kù)實(shí)例可以針對(duì)請(qǐng)求中提交的所有命令用單次響應(yīng)向數(shù)據(jù)庫(kù)客戶端返回結(jié)果。在單次交互的請(qǐng)求和響應(yīng)中處理多條命令可以導(dǎo)致對(duì)數(shù)據(jù)庫(kù)連接的高效使用。換句話說(shuō),在允許通過(guò)使用數(shù)據(jù)庫(kù)連接的請(qǐng)求提交多條命令時(shí),客戶端通常使用數(shù)據(jù)庫(kù)連接來(lái)提交請(qǐng)求的頻率就比較低。
[0017]應(yīng)用程序和邏輯連接
[0018]服務(wù)器例如中間層服務(wù)器(mid-tier server)為從數(shù)據(jù)庫(kù)請(qǐng)求信息的應(yīng)用程序提供數(shù)據(jù)庫(kù)實(shí)例連接。中間層服務(wù)器是提供對(duì)一個(gè)或多個(gè)數(shù)據(jù)庫(kù)服務(wù)器的訪問(wèn)、向一個(gè)或多個(gè)數(shù)據(jù)庫(kù)服務(wù)器分配工作或者管理連往一個(gè)或多個(gè)數(shù)據(jù)庫(kù)服務(wù)器的連接的服務(wù)器。應(yīng)用程序是在一種或多種計(jì)算設(shè)備上運(yùn)行的利用數(shù)據(jù)庫(kù)連接從數(shù)據(jù)庫(kù)中檢索信息的任意邏輯。檢索的信息可以展示或顯示給應(yīng)用程序的用戶。例如,應(yīng)用程序可以通過(guò)瀏覽器訪問(wèn),其中應(yīng)用程序從用戶處接收輸入并且向用戶展示信息。應(yīng)用程序可以是由用戶在網(wǎng)絡(luò)上通過(guò)門戶網(wǎng)站訪問(wèn)的應(yīng)用程序、安裝在用戶機(jī)器上的應(yīng)用程序或者是分布在多臺(tái)機(jī)器上的應(yīng)用程序。
[0019]在一個(gè)示例中,Oracle? Fnslon⑩應(yīng)用程序?qū)iT設(shè)置用于從Oracle?數(shù)據(jù)庫(kù)中檢索數(shù)據(jù)并且向Fusion⑩應(yīng)用程序的用戶顯示信息。目前就有不同于Oracle⑧Vision⑩..應(yīng)用程序的應(yīng)用程序,并且在將來(lái)也可以開發(fā)出其他的數(shù)據(jù)庫(kù)應(yīng)用程序而并不背離本公開。
[0020]在一個(gè)示例中,應(yīng)用程序針對(duì)數(shù)據(jù)庫(kù)中的數(shù)據(jù)向中間層服務(wù)器發(fā)出請(qǐng)求。請(qǐng)求可以也可以不響應(yīng)于用戶輸入而發(fā)送。中間層服務(wù)器從自由連接的連接池中選擇連往數(shù)據(jù)庫(kù)實(shí)例的自由連接。已被客戶端或客戶端群組選擇和/或定制使用的數(shù)據(jù)庫(kù)連接在本文中被稱作“數(shù)據(jù)庫(kù)會(huì)話”。數(shù)據(jù)庫(kù)連接可以定制以滿足作為用于特定客戶端的數(shù)據(jù)庫(kù)會(huì)話的特定需求,或者連接可以規(guī)范化以使得連接能夠被用于支持各種客戶端所用的各種數(shù)據(jù)庫(kù)會(huì)話。中間層服務(wù)器通過(guò)選擇的連接向數(shù)據(jù)庫(kù)實(shí)例發(fā)送客戶端請(qǐng)求,并且數(shù)據(jù)庫(kù)實(shí)例訪問(wèn)數(shù)據(jù)庫(kù)以處理請(qǐng)求。數(shù)據(jù)庫(kù)服務(wù)器通過(guò)檢索或修改數(shù)據(jù)庫(kù)內(nèi)的數(shù)據(jù)或者通過(guò)檢索或修改數(shù)據(jù)庫(kù)中的數(shù)據(jù)緩存內(nèi)的數(shù)據(jù)來(lái)處理請(qǐng)求。在數(shù)據(jù)庫(kù)服務(wù)器處理請(qǐng)求時(shí),數(shù)據(jù)庫(kù)服務(wù)器建立起用于數(shù)據(jù)庫(kù)會(huì)話的狀態(tài)。
[0021]中間層服務(wù)器經(jīng)常存留連接池,其中包括連往數(shù)據(jù)庫(kù)實(shí)例的連接。連接可以表示物理機(jī)構(gòu)例如物理端口或邏輯接口或者兩者兼有??梢源嬖谶壿嬤B接(也就是數(shù)據(jù)庫(kù)會(huì)話)到物理連接的一對(duì)一映射。另一方面,可以存在多于一個(gè)跟單個(gè)物理連接相關(guān)聯(lián)的邏輯連接。在一個(gè)示例中,連接池內(nèi)的自由連接僅包括尚未分配給用于處理請(qǐng)求的應(yīng)用程序的那些連接。在工作完成后,連接即被送回連接池并且可供后續(xù)應(yīng)用程序從池中借出。
[0022]在一個(gè)示例中,中間層服務(wù)器將邏輯連接分配給請(qǐng)求訪問(wèn)數(shù)據(jù)庫(kù)的應(yīng)用程序。邏輯連接被直接或間接地映射至多個(gè)物理連接中的一個(gè)。邏輯連接可以重新分配給新的物理連接而無(wú)需為應(yīng)用程序重新分配新的邏輯連接。邏輯連接可以暴露給應(yīng)用程序,并且應(yīng)用程序可以在底層的物理連接改變時(shí)繼續(xù)引用相同的邏輯連接。在一個(gè)示例中,特定的邏輯連接被表示為一個(gè)連接對(duì)象,該連接對(duì)象暴露給應(yīng)用程序并且映射至另一個(gè)可以也可以不暴露給應(yīng)用程序且可以是也可以不是另一個(gè)邏輯連接的連接對(duì)象。通過(guò)邏輯連接的層級(jí)將特定的邏輯連接映射至物理連接。
[0023]數(shù)據(jù)庫(kù)會(huì)話不可用對(duì)應(yīng)用程序的影響
[0024]在應(yīng)用程序利用數(shù)據(jù)庫(kù)會(huì)話來(lái)訪問(wèn)數(shù)據(jù)庫(kù)時(shí),應(yīng)用程序建立起關(guān)于數(shù)據(jù)庫(kù)會(huì)話的狀態(tài)。例如,應(yīng)用程序利用數(shù)據(jù)庫(kù)會(huì)話來(lái)獲取鎖、創(chuàng)建臨時(shí)變量或數(shù)據(jù)庫(kù)對(duì)象、建立用戶專用信息、建立應(yīng)用程序?qū)S眯畔ⅰ⒔⒐鈽?biāo)信息、建立數(shù)據(jù)的臨時(shí)配置或選擇和/或執(zhí)行關(guān)于數(shù)據(jù)的其他部分完成操作以用于數(shù)據(jù)庫(kù)會(huì)話中的后續(xù)處理。如果數(shù)據(jù)庫(kù)會(huì)話在后續(xù)處理進(jìn)行之前出錯(cuò),那么鎖、臨時(shí)變量或數(shù)據(jù)庫(kù)對(duì)象、用戶專用信息、應(yīng)用程序?qū)S眯畔?、光?biāo)信息、數(shù)據(jù)的臨時(shí)配置或選擇和/或部分完成的操作就變?yōu)閷?duì)應(yīng)用程序不可用,即使是應(yīng)用程序試圖在新的數(shù)據(jù)庫(kù)會(huì)話中引用這些信息也不行。
[0025]在一個(gè)示例中,如果數(shù)據(jù)庫(kù)會(huì)話所依賴的數(shù)據(jù)庫(kù)實(shí)例出錯(cuò)或以其他方式變?yōu)椴豢捎?,那么?shù)據(jù)庫(kù)會(huì)話就可以出錯(cuò)或以其他方式變?yōu)椴豢捎?。在大多?shù)情況下,數(shù)據(jù)庫(kù)會(huì)話出錯(cuò)會(huì)導(dǎo)致應(yīng)用程序由于進(jìn)行中的數(shù)據(jù)庫(kù)會(huì)話丟失而出錯(cuò)。應(yīng)用程序的用戶必須重啟應(yīng)用程序或應(yīng)用程序的組件并且從登錄開始,打開光標(biāo)并檢索數(shù)據(jù),獲取鎖,創(chuàng)建臨時(shí)變量或數(shù)據(jù)庫(kù)對(duì)象,建立用戶專用信息,建立應(yīng)用程序?qū)S眯畔ⅲ⒐鈽?biāo)信息,建立數(shù)據(jù)的臨時(shí)配置或選擇和/或部分完成對(duì)數(shù)據(jù)的操作以用于數(shù)據(jù)庫(kù)會(huì)話中的后續(xù)處理。在一個(gè)示例中,一旦數(shù)據(jù)庫(kù)會(huì)話出錯(cuò),用戶可以得到死機(jī)的藍(lán)屏或者被錯(cuò)誤信息中斷。
[0026]在現(xiàn)有的客戶端-服務(wù)器系統(tǒng)中,如果在客戶端和服務(wù)器之間有中斷,那么客戶端就會(huì)看到指示通信出錯(cuò)的錯(cuò)誤信息。這種報(bào)錯(cuò)不會(huì)告知客戶端提交是否執(zhí)行了任何交付操作,或者過(guò)程調(diào)用是運(yùn)行完成了所有預(yù)期交付的執(zhí)行和會(huì)話狀態(tài)的改變還是中途出錯(cuò)或者是更加糟糕地在從客戶端斷開后仍保持運(yùn)行。
[0027]如果客戶端想要獲知向數(shù)據(jù)庫(kù)的提交是否已交付,那么客戶端應(yīng)該加入自定義異常碼以針對(duì)應(yīng)用程序中每一個(gè)可能的交付點(diǎn)查詢輸出。考慮到系統(tǒng)在任何地方都有可能出錯(cuò),由于必須專門針對(duì)每一次提交進(jìn)行查詢,因此這通常都不現(xiàn)實(shí)。在應(yīng)用程序已建立并投入生產(chǎn)后,這是完全不切實(shí)際的。而且,因?yàn)槭聞?wù)可能會(huì)在執(zhí)行查詢之后立刻交付,所以查詢并不能給出準(zhǔn)確答案。實(shí)際上,在通信出錯(cuò)之后,服務(wù)器仍然可能運(yùn)行提交而并未意識(shí)到客戶端已斷開。對(duì)于PL/SQL或Java操作或提交給數(shù)據(jù)庫(kù)的其他過(guò)程,并沒(méi)有關(guān)于過(guò)程的提交是已運(yùn)行完成還是中途異常終止的記錄。盡管可能已經(jīng)交付,但是針對(duì)該過(guò)程的后續(xù)工作可能仍未完成。
[0028]無(wú)法識(shí)別出最終提交是已交付還是應(yīng)該在隨后的某一時(shí)刻交付還是并未運(yùn)行完成能夠由于用戶和軟件可能嘗試重新提出已經(jīng)存留的改變而導(dǎo)致重復(fù)的事務(wù)提交和其他形式的“邏輯訛誤”。
[0029]現(xiàn)有技術(shù)并未提供在資源變?yōu)椴豢捎脮r(shí)由所述資源執(zhí)行的工作的相關(guān)信息。例如,應(yīng)用程序在停機(jī)、有計(jì)劃或無(wú)計(jì)劃的情況下無(wú)法獲知由所述資源處理的最后一次操作的輸出。如果服務(wù)器在執(zhí)行命令集時(shí)并且在服務(wù)器向客戶端發(fā)送對(duì)命令集的響應(yīng)之前宕機(jī),那么客戶端就無(wú)法獲知在停機(jī)之前命令集是否已被服務(wù)器執(zhí)行。即使是高度復(fù)雜的應(yīng)用程序也可能會(huì)向終端用戶暴露出停機(jī)問(wèn)題。[0030]體驗(yàn)到資源停機(jī)的用戶可能會(huì)很失望并且可能會(huì)由于錯(cuò)失業(yè)務(wù)機(jī)會(huì)、利用不良數(shù)據(jù)做出決策、故障檢修的開銷以及重啟應(yīng)用程序或重做工作損失的時(shí)間而損失收益。某些應(yīng)用程序警告用戶不得點(diǎn)擊提交按鈕兩次,但是在用戶未留意到不能這樣做的警告時(shí),如果兩次提交都允許完成,那么就會(huì)建立重復(fù)的事務(wù)。
[0031]在另一個(gè)示例中,一旦數(shù)據(jù)庫(kù)會(huì)話出錯(cuò),在重載頁(yè)面之前就禁止用戶輸入任何信息或者促使將任何命令提交給數(shù)據(jù)庫(kù)。而且,不校驗(yàn)有哪些數(shù)據(jù)被存入數(shù)據(jù)庫(kù)就重載頁(yè)面可能會(huì)導(dǎo)致重復(fù)提交。應(yīng)用程序可以禁止用戶提交跟出錯(cuò)的數(shù)據(jù)庫(kù)會(huì)話中丟失的狀態(tài)有關(guān)或者如果所需信息不再可用就可能誤操作的任何命令。在一個(gè)特定的示例中,已經(jīng)展示給用戶的域可以變灰以表示為了避免破壞數(shù)據(jù)庫(kù)內(nèi)存儲(chǔ)的數(shù)據(jù),這些域不能再通過(guò)應(yīng)用程序修改。
[0032]即使數(shù)據(jù)庫(kù)會(huì)話在用于第二數(shù)據(jù)庫(kù)實(shí)例的過(guò)程中出錯(cuò),第二數(shù)據(jù)庫(kù)實(shí)例可能也無(wú)法獲得在出錯(cuò)前交付給數(shù)據(jù)庫(kù)的內(nèi)容以外的任何關(guān)于數(shù)據(jù)庫(kù)會(huì)話的信息。為了避免破壞數(shù)據(jù)庫(kù)內(nèi)的數(shù)據(jù),應(yīng)用程序可以將顯示給用戶的信息重設(shè)為跟已經(jīng)交付給數(shù)據(jù)庫(kù)的數(shù)據(jù)相匹配的信息。換句話說(shuō),在數(shù)據(jù)庫(kù)實(shí)例出錯(cuò)時(shí),用戶可能會(huì)丟失恰好在出錯(cuò)前已經(jīng)可為用戶所用的臨時(shí)信息。部分丟失的信息可以對(duì)應(yīng)于被使用當(dāng)前可用數(shù)據(jù)庫(kù)會(huì)話的應(yīng)用程序和/或用戶顯示、修改、選擇或設(shè)置的信息或者將要通過(guò)現(xiàn)已不可用的數(shù)據(jù)庫(kù)會(huì)話返回給應(yīng)用程序和/或用戶的信息。用戶經(jīng)常被迫再次重新輸入各域的數(shù)據(jù)。
[0033]丟失已由用戶輸入、修改、選擇和/或設(shè)置的信息可能會(huì)導(dǎo)致用戶失望以及在應(yīng)用程序或應(yīng)用程序組件重啟之后重新輸入、重新修改、重新選擇和/或重新設(shè)置信息上浪費(fèi)時(shí)間。丟失的信息可以是由用戶從其他來(lái)源例如視頻、音頻、郵件或文本消息中檢索到的信息。在某些情況下,丟失的信息可能無(wú)法再進(jìn)行檢索。在發(fā)生故障且此時(shí)用戶正接受支持服務(wù)提供商的幫助時(shí),丟失信息的代價(jià)可能會(huì)特別高。丟失信息可能需要跟支持服務(wù)提供商進(jìn)一步通信,或者甚至可能會(huì)導(dǎo)致用戶喪失對(duì)應(yīng)用程序、中間層服務(wù)器或數(shù)據(jù)庫(kù)服務(wù)器或者提供應(yīng)用程序、中間層服務(wù)器或數(shù)據(jù)庫(kù)服務(wù)器的公司的可靠性的信心。此外,用戶可以在出錯(cuò)之前選擇、輸入或修改對(duì)時(shí)間敏感的信息。要求用戶在出錯(cuò)之后重新輸入對(duì)時(shí)間敏感的信息可能會(huì)導(dǎo)致延時(shí),從而造成業(yè)務(wù)、價(jià)值或用戶對(duì)業(yè)務(wù)客戶的信譽(yù)或用戶的業(yè)務(wù)投資方面的損失。要求重新輸入還可能會(huì)導(dǎo)致用戶錯(cuò)失機(jī)會(huì)。例如,用戶可能會(huì)遺漏用戶先前已選擇的事項(xiàng)或機(jī)會(huì)。
[0034]在本部分介紹的方法是能夠推行的方法但不一定是先前已經(jīng)設(shè)想或推行過(guò)的方法。因此,除非另有說(shuō)明,否則不應(yīng)認(rèn)為在這本部分介紹的任何方法僅由于包含在本部分內(nèi)就構(gòu)成現(xiàn)有技術(shù)。
[0035]快速應(yīng)用程序通知
[0036]應(yīng)用程序開發(fā)商開發(fā)了處理服務(wù)器-客戶端系統(tǒng)中的底層軟件、硬件、底層通信層或其他資源的報(bào)告停機(jī)的應(yīng)用程序。例如,對(duì)于OraclelOg,快速應(yīng)用程序通知(“FAN”)在資源增加(也就是變?yōu)榭捎?或減少(也就是變?yōu)椴豢捎?時(shí)向應(yīng)用程序發(fā)送通知,并且應(yīng)用程序開發(fā)商可以將其應(yīng)用程序定制為響應(yīng)于通知而改變應(yīng)用程序的行為。
【專利附圖】
【附圖說(shuō)明】
[0037]在附圖中:[0038]圖1示出了用于保存數(shù)據(jù)庫(kù)系統(tǒng)內(nèi)的事務(wù)狀態(tài)的示例性步驟。
[0039]圖2示出了用于管理數(shù)據(jù)庫(kù)系統(tǒng)內(nèi)的邏輯事務(wù)標(biāo)識(shí)符(“LTXID”)的示例性步驟。
[0040]圖3和圖4示出了用于在事務(wù)開啟并且執(zhí)行數(shù)據(jù)定義語(yǔ)言(“DDL”)的語(yǔ)句時(shí)保存數(shù)據(jù)庫(kù)系統(tǒng)內(nèi)事務(wù)狀態(tài)的示例性步驟。
[0041]圖5示出了用于在數(shù)據(jù)庫(kù)管理系統(tǒng)內(nèi)執(zhí)行事務(wù)性命令集的示例性步驟。
[0042]圖6示出了用于在執(zhí)行并行輸入操作語(yǔ)言(“PDML”)的語(yǔ)句時(shí)管理數(shù)據(jù)庫(kù)系統(tǒng)內(nèi)事務(wù)狀態(tài)的示例性步驟。
[0043]圖7示出了可以在數(shù)據(jù)庫(kù)系統(tǒng)內(nèi)執(zhí)行的示例性分布式事務(wù)。
[0044]圖8示出了用于保存數(shù)據(jù)庫(kù)系統(tǒng)內(nèi)的事務(wù)狀態(tài)的示例性方法的各個(gè)階段。
[0045]圖9示出了客戶端利用數(shù)據(jù)庫(kù)會(huì)話訪問(wèn)數(shù)據(jù)庫(kù)的示例性結(jié)構(gòu)。
[0046]圖10示出了用于確定事務(wù)性命令集輸出的示例性方法。
[0047]圖11示出了用于強(qiáng)制執(zhí)行命令集的示例性方法。
[0048]圖12示出了用于檢查客戶端是否跟服務(wù)器同步的示例性方法。
[0049]圖13示出了用于管理連接對(duì)象的示例性方法,所述連接對(duì)象包括會(huì)話識(shí)別信息以及用于在標(biāo)識(shí)的會(huì)話內(nèi)識(shí)別事務(wù)性命令集的信息。
[0050]圖14示出了用于存留事務(wù)性命令集記錄的示例性方法。
[0051]圖15示出了可以被專門設(shè)置用于執(zhí)行本文所述示例性方法的示例性計(jì)算機(jī)系統(tǒng)。
【具體實(shí)施方式】
[0052]在以下的說(shuō)明內(nèi)容中,為了便于解釋,列舉了很多具體的細(xì)節(jié)以提供對(duì)本發(fā)明的全面理解。但顯而易見(jiàn)的是無(wú)需這些具體細(xì)節(jié)即可實(shí)現(xiàn)本發(fā)明。在其他的情況下,為了避免不必要地混淆本發(fā)明而以框圖的形式示出了公知的結(jié)構(gòu)和設(shè)備。
[0053]概述
[0054]本文公開了用于恢復(fù)數(shù)據(jù)庫(kù)會(huì)話狀態(tài)的技術(shù)。換句話說(shuō),所述技術(shù)能夠被用于確定事務(wù)性命令集是否已完成或部分完成。例如,若一項(xiàng)或多項(xiàng)事務(wù)已經(jīng)交付但是還有一項(xiàng)或多項(xiàng)另外的事務(wù)尚未交付,如果還要通過(guò)用于命令集的交付輸出來(lái)返回更多的信息,或者如果還要由服務(wù)器以其他方式做更多的工作來(lái)完成命令集,那么命令集可為部分完成。盡管所述技術(shù)可以參照具體的實(shí)施例進(jìn)行介紹,本文介紹的功能可以通過(guò)方法的實(shí)施、通過(guò)在執(zhí)行時(shí)促使所述方法實(shí)施的一條或多條存儲(chǔ)指令的集合或者通過(guò)專門設(shè)置用于實(shí)施所述方法的一臺(tái)或多臺(tái)機(jī)器的集合來(lái)提供。
[0055]在一個(gè)實(shí)施例中,會(huì)話中最新事務(wù)性命令集的相關(guān)信息可以被存儲(chǔ)在響應(yīng)于對(duì)會(huì)話的請(qǐng)求而發(fā)送至客戶端的連接對(duì)象內(nèi)。在一種示例性方法中,客戶端在身份驗(yàn)證時(shí)、在校驗(yàn)時(shí)接收邏輯標(biāo)識(shí)符例如邏輯事務(wù)ID(LTXID),并且在每一次交付時(shí)接收對(duì)該LTXID的更新。在示例中,每一次完成交付操作或者每一次完成包括至少一項(xiàng)交付操作的命令集都可以促使服務(wù)器實(shí)例為客戶端提供新的或更新的LTXID。如果來(lái)自客戶端的下一個(gè)命令集被交付,那么客戶端就基于來(lái)自服務(wù)器的更新存留要在服務(wù)器處使用的下一個(gè)LTXID。服務(wù)器實(shí)例存儲(chǔ)并控制變化的LTXID。在示例中,服務(wù)器實(shí)例將該信息存儲(chǔ)或存留在會(huì)話所用的連接對(duì)象內(nèi)。[0056]在一個(gè)實(shí)施例中,連接對(duì)象是JDBC連接對(duì)象或OCI服務(wù)句柄或ODP.Net連接對(duì)象??蛻舳藨?yīng)用程序從客戶端庫(kù)獲取連接對(duì)象,并且客戶端庫(kù)利用連接對(duì)象打開連往服務(wù)器的物理連接(接口)??蛻舳藥?kù)向服務(wù)器輸送信息以使服務(wù)器能夠驗(yàn)證客戶端的身份并確定客戶端的特權(quán)。直到連接對(duì)象被返回連接池之前,連接對(duì)象都保持分配給同一個(gè)應(yīng)用程序。
[0057]第一服務(wù)器在第一會(huì)話中從客戶端接收多個(gè)事務(wù)性命令集。如果通過(guò)一個(gè)命令集促使的任何事務(wù)被交付,那么用于該命令集的邏輯事務(wù)ID(LTXID)即被作為該交付操作的一部分存儲(chǔ)。如果存在已經(jīng)交付的事務(wù)和尚未交付的事務(wù),那么存儲(chǔ)的信息就指明命令集處于中間狀態(tài)或嵌入狀態(tài)。在一個(gè)實(shí)施例中,客戶端在客戶端和服務(wù)器之間的每一次交互期間都向服務(wù)器發(fā)送命令集以用于執(zhí)行。在包括交付的任何命令集之后,用于該命令集的LTXID被更新以反映事務(wù)的完成,并且更新的LTXID被發(fā)送至客戶端并存留在連接對(duì)象中。例如,LTXID可以與通過(guò)執(zhí)行事務(wù)性命令集獲得的任何結(jié)果一起發(fā)送至客戶端。如果在事務(wù)性命令集中尚未交付任何事務(wù),那么客戶端就具有在當(dāng)前事務(wù)性命令集之前由客戶端發(fā)送用于執(zhí)行的先前事務(wù)性命令集的LTXID。
[0058]在一個(gè)實(shí)施例中,任何交付都會(huì)導(dǎo)致LTXID的增加和返回新的LTXID。如果包含交付的命令集已經(jīng)交付且完成,那么記錄的LTXID (也就是先前的LTXID)就具有包括“已完成”命令集的狀態(tài)或輸出。在本實(shí)施例中,每一次交付都導(dǎo)致更新同一個(gè)會(huì)話的最新LTXID。在另一個(gè)實(shí)施例中,每一個(gè)完成的事務(wù)性命令集都導(dǎo)致更新同一個(gè)會(huì)話的最新LTXID。
[0059]第二服務(wù)器在第二會(huì)話中從客戶端接收例如通過(guò)利用先前送至客戶端的邏輯標(biāo)識(shí)符來(lái)識(shí)別特定命令集的請(qǐng)求。第二服務(wù)器確定所述請(qǐng)求是否識(shí)別出接收用于在第一會(huì)話中執(zhí)行的最新事務(wù)性命令集。如果答案為否,那么第二服務(wù)器可以將客戶端尚未跟服務(wù)器同步的消息通知客戶端。
[0060]第二服務(wù)器也可以確定在特定的命令集內(nèi)是否尚未交付由特定命令集促使的事務(wù),第二服務(wù)器通過(guò)阻止由該LTXID標(biāo)識(shí)的事務(wù)免于交付來(lái)強(qiáng)行設(shè)定任何未交付狀態(tài)從而保證輸出。未交付狀態(tài)包括如果第一會(huì)話已成功完成則本應(yīng)在第一會(huì)話中交付但是因?yàn)榈谝粫?huì)話并未完成而未能交付的任何狀態(tài)。強(qiáng)行設(shè)定未交付狀態(tài)避免了未交付狀態(tài)在隨后一旦另一個(gè)會(huì)話將未交付狀態(tài)作為未交付處理后變?yōu)榻桓?。一旦被阻止,第二服?wù)器就可以通知客戶端由該邏輯事務(wù)ID標(biāo)識(shí)的命令集并未交付。一旦命令集已被阻止,第二服務(wù)器就可以通知客戶端標(biāo)識(shí)的事務(wù)并未交付(或者標(biāo)識(shí)的事件并未發(fā)生)。第二服務(wù)器還可以促使執(zhí)行第二會(huì)話中的特定命令集,由此在第一會(huì)話已被阻止之后促使事務(wù)或事件在第二會(huì)話中第一次發(fā)生。
[0061]第二服務(wù)器還要確定由特定命令集促使的至少一項(xiàng)事務(wù)是否已交付以及由特定命令集促使的任何其他事務(wù)是否尚未交付,或者是否可能仍未交付,或者在所述交付之后是否還有更多操作。在同一個(gè)實(shí)施例或各種其他的實(shí)施例中,第二服務(wù)器可以確定是否丟失了某種會(huì)話狀態(tài)的改變和/或是否丟失了來(lái)自客戶端的結(jié)果。如果事務(wù)已經(jīng)交付但是在交付之后還有更多工作要做,那么服務(wù)器可以指示客戶端所述交付是中間“嵌入”狀態(tài)??蛻舳丝梢岳媒桓稜顟B(tài)并且可以根據(jù)是否需要完成狀態(tài)來(lái)選擇繼續(xù)與否。
[0062]在本文提供的各種示例中,數(shù)據(jù)庫(kù)系統(tǒng)從數(shù)據(jù)庫(kù)事務(wù)層的角度提供事務(wù)冪等性并且利用邏輯事務(wù)ID將對(duì)該信息的訪問(wèn)擴(kuò)展至客戶端。換句話說(shuō),數(shù)據(jù)庫(kù)系統(tǒng)內(nèi)的服務(wù)器記錄由服務(wù)器利用邏輯事務(wù)ID交付的事務(wù),并且服務(wù)器還通過(guò)利用邏輯事務(wù)ID阻止那些并未交付的事務(wù)來(lái)避免多于一次地完成事務(wù)。事務(wù)是改變數(shù)據(jù)的操作集合。在數(shù)據(jù)庫(kù)系統(tǒng)中,操作通過(guò)一條或多條數(shù)據(jù)庫(kù)命令來(lái)明確。交付事務(wù)是指對(duì)事務(wù)的改變?cè)跀?shù)據(jù)庫(kù)內(nèi)不變。為了保持?jǐn)?shù)據(jù)的完整性,在交付事務(wù)時(shí)通過(guò)事務(wù)做出的改變以全做或不做的方式精確地(atomically)完成。要么交付所有的改變,要么就將事務(wù)退回重來(lái)。在永久性地完成事務(wù)時(shí),邏輯事務(wù)標(biāo)識(shí)符在交付時(shí)被記錄為該事務(wù)的一部分。在交付后,將要使用的下一個(gè)邏輯事務(wù)標(biāo)識(shí)符返回給客戶端。在一個(gè)實(shí)施例中,構(gòu)成邏輯事務(wù)ID—部分的運(yùn)行交付編號(hào)在每一次交付完成后或者在包括至少一次交付的每一個(gè)命令集完成后被遞增并返回給客戶端作為L(zhǎng)TXID的一部分。
[0063]在一個(gè)實(shí)施例中,如果第一數(shù)據(jù)庫(kù)會(huì)話在處理事務(wù)時(shí)經(jīng)歷停機(jī)(outage),那么通過(guò)在第二會(huì)話中阻止由該LTXID標(biāo)識(shí)的事務(wù)免于在第一會(huì)話交付而強(qiáng)行設(shè)定未交付狀態(tài),所述事務(wù)就可以在不同的第二數(shù)據(jù)庫(kù)會(huì)話中完成而并沒(méi)有仍要讓會(huì)話在第一數(shù)據(jù)庫(kù)會(huì)話中完成的風(fēng)險(xiǎn)。即使在一個(gè)會(huì)話中執(zhí)行了多項(xiàng)事務(wù),服務(wù)器也可以透明地并且以標(biāo)定跟多個(gè)服務(wù)器的多個(gè)會(huì)話中的多個(gè)客戶端的方式向客戶端提供事務(wù)冪等性。
[0064]在一個(gè)實(shí)施例中,即使事務(wù)的執(zhí)行在第一次嘗試期間并未完成,服務(wù)器也允許交付事件。服務(wù)器在針對(duì)數(shù)據(jù)庫(kù)交付事務(wù)時(shí)保存邏輯事務(wù)標(biāo)識(shí)符(“LTXID”)。這些事務(wù)可以包括例如從內(nèi)部PL/SQL、從內(nèi)部服務(wù)器方的Java、從遠(yuǎn)程事務(wù)、從并行事務(wù)、從分布式事務(wù)以及從不能另外利用常規(guī)手段識(shí)別的標(biāo)注中利用自動(dòng)交付執(zhí)行的事務(wù)。服務(wù)器利用LTXID支持最多一次的執(zhí)行語(yǔ)義以使得無(wú)論是否存在多個(gè)進(jìn)行中的事務(wù)副本,由LTXID保護(hù)的數(shù)據(jù)庫(kù)事務(wù)都不能重復(fù)。換句話說(shuō),客戶端可以提交若干次請(qǐng)求以完成同一項(xiàng)事務(wù),并且服務(wù)器可以避免事務(wù)被完成多于一次。
[0065]在一個(gè)實(shí)施例中,服務(wù)器阻止進(jìn)行中工作的交付以確保無(wú)論停機(jī)狀況如何,通過(guò)例如瀏覽器或中間層客戶端對(duì)同一項(xiàng)事務(wù)的再一次提交不能交付。服務(wù)器可以通過(guò)利用針對(duì)要重新提交該事務(wù)的每一次嘗試的邏輯事務(wù)ID(LTXID)記錄受完成事務(wù)的不同嘗試影響的事務(wù)狀態(tài)而識(shí)別完成同一項(xiàng)事務(wù)的重復(fù)嘗試。例如,當(dāng)服務(wù)器在命令集已被提交供執(zhí)行的情況下嘗試分解命令集時(shí),服務(wù)器可以通過(guò)將代表事務(wù)性命令集的邏輯事務(wù)ID更新為阻止?fàn)顟B(tài)而強(qiáng)行設(shè)定未交付狀態(tài)。
[0066]在一個(gè)實(shí)施例中,服務(wù)器記錄針對(duì)跟LTXID相關(guān)聯(lián)的命令集而交付的工作。服務(wù)器可以識(shí)別工作是作為頂層調(diào)用(客戶端到服務(wù)器)的一部分而交付還是被嵌入在服務(wù)器處的過(guò)程例如PL/SQL或Java過(guò)程中還是構(gòu)成涉及返回其他信息例如輸出賦值或返回消息的交付操作的一部分。服務(wù)器可以存儲(chǔ)命令集具有嵌入交付狀態(tài)的指示。嵌入的交付狀態(tài)標(biāo)識(shí)在交付完成時(shí)執(zhí)行交付的整個(gè)過(guò)程尚未運(yùn)行完成。交付以外的任何工作直到父過(guò)程在數(shù)據(jù)庫(kù)服務(wù)器返回并且所有結(jié)果都已由客戶端接收之后才能確保完成。
[0067]在一個(gè)實(shí)施例中,如果客戶端請(qǐng)求分解提交的事務(wù),那么服務(wù)器就識(shí)別數(shù)據(jù)庫(kù)系統(tǒng)是超前、同步還是落后于最初的提交。服務(wù)器可以在來(lái)自客戶端的事務(wù)提交序列中有間隙時(shí)拒絕客戶端的請(qǐng)求。如果客戶端嘗試強(qiáng)行完成事務(wù),為此服務(wù)器或客戶端在LTXID序列上不同步,那么服務(wù)器可以通知客戶端同步錯(cuò)誤。
[0068]在一個(gè)實(shí)施例中,客戶端驅(qū)動(dòng)器設(shè)有在LTXID通過(guò)從客戶端到服務(wù)器的交付調(diào)用而遞增時(shí)生效的回調(diào)?;卣{(diào)由更高層的應(yīng)用程序例如Oracle的WebLogicServer和第三方應(yīng)用程序使用以記錄在客戶端的當(dāng)前LTXID。即使是客戶端的數(shù)據(jù)庫(kù)會(huì)話變?yōu)椴豢捎?,客戶端也可以引用?dāng)前的LTXID。
[0069]在一個(gè)實(shí)施例中,LTXID被分配以確保命名空間在全局不同的數(shù)據(jù)庫(kù)以及整合為可插入架構(gòu)的數(shù)據(jù)庫(kù)上的唯一性。
[0070]在一個(gè)實(shí)施例中,如果在該會(huì)話中來(lái)自客戶端的任意調(diào)用集合成功交付了任何工作,服務(wù)器就遞增交付序列。在用于調(diào)用的返回碼返回到客戶端時(shí),將包括交付編號(hào)的邏輯事務(wù)ID跟客戶端共享。交付序列被用于保持會(huì)話排序。以穩(wěn)定的方式更新序列允許服務(wù)器驗(yàn)證客戶端和服務(wù)器是否同步(也就是LTXID相同)。以穩(wěn)定的方式更新序列還可以允許客戶端確定下一個(gè)LTXID,不過(guò)如果LTXID處理是在服務(wù)器進(jìn)行那就不需要這樣做。如果LTXID處理是在服務(wù)器進(jìn)行,客戶端可以僅存留LTXID例如用于在先前的會(huì)話變?yōu)椴豢捎脮r(shí)返回給新的會(huì)話。更新序列和序列狀態(tài)的永久記錄允許永久記錄的成長(zhǎng)跟會(huì)話數(shù)量而不是可能大得多的事務(wù)數(shù)量成比例。跟事務(wù)成比例的成長(zhǎng)與跟會(huì)話成比例的更加有限的成長(zhǎng)相比可能要使用更多的空間、內(nèi)存和處理功率。
[0071]在一個(gè)實(shí)施例中,即使在停機(jī)前送回客戶端的交付消息并未提供這樣的信息,客戶端通常也可以確定停機(jī)后最后一次交付操作的輸出。服務(wù)器通過(guò)強(qiáng)行設(shè)定用于進(jìn)行中和由于停機(jī)而退回重來(lái)的事務(wù)的未交付狀態(tài)來(lái)確保將交付結(jié)果送回客戶端。通過(guò)使該信息對(duì)客戶端可用,服務(wù)器幫助客戶端避免重復(fù)的事務(wù)提交以及如果用戶和應(yīng)用程序嘗試重新發(fā)起已經(jīng)交付數(shù)據(jù)庫(kù)的改變而可能導(dǎo)致的其他形式的“邏輯誰(shuí)誤(logical Corruption) ”。
[0072]在一個(gè)實(shí)施例中,客戶端不需要存留關(guān)聯(lián)至特定數(shù)據(jù)庫(kù)對(duì)象的修改編號(hào)??蛻舳丝梢酝ㄟ^(guò)查詢邏輯標(biāo)識(shí)符而不是受命令影響的對(duì)象來(lái)確定命令集是否已完成。例如,客戶端可以利用LTXID查詢命令集而不必考慮可能受事務(wù)性命令集影響的數(shù)據(jù)對(duì)象,從而就事務(wù)性命令集是否已經(jīng)完成進(jìn)行探查。
[0073]在一個(gè)實(shí)施例中,客戶端無(wú)需為了確定過(guò)去提交的事務(wù)是否已交付以及這些交付是否已完成而提交另外的事務(wù)。例如,在每一次客戶端提交可能會(huì)向數(shù)據(jù)庫(kù)交付改變的其他命令時(shí),客戶端無(wú)需提交更新數(shù)據(jù)庫(kù)中的事務(wù)歷史表的DML命令。事務(wù)歷史表可以在客戶端提交事務(wù)性命令集時(shí)自動(dòng)更新而無(wú)需客戶端提交單獨(dú)的語(yǔ)句來(lái)更新事務(wù)歷史表。提交這些其他的語(yǔ)句將會(huì)造成服務(wù)器和客戶端之間流量的明顯增加。
[0074]在一個(gè)實(shí)施例中,服務(wù)器不允許客戶端僅因?yàn)樵诳蛻舳讼惹皺z查命令集的輸出時(shí)事務(wù)性命令集尚未完成而重新提交事務(wù)性命令集。在重新執(zhí)行命令集之前,服務(wù)器可以例如通過(guò)使用邏輯事務(wù)ID阻止事務(wù)歷史表內(nèi)的狀態(tài)來(lái)嘗試確定最后一項(xiàng)事務(wù)是否交付。如果先前會(huì)話中的另一個(gè)服務(wù)器已經(jīng)更新了事務(wù)歷史表來(lái)反映命令集已交付,那么第二服務(wù)器就指示客戶端標(biāo)識(shí)的事務(wù)已交付。換句話說(shuō),如果在更新事務(wù)歷史表之前命令集已經(jīng)在先前的會(huì)話中交付,那么在新會(huì)話中利用相同的LTXID重新執(zhí)行的任何嘗試都被交付狀態(tài)阻止。但是,如果在測(cè)試事務(wù)歷史表之前命令集并未在先前的會(huì)話中交付,那么先前會(huì)話中完成的事務(wù)即被阻止以使命令可以在新會(huì)話中無(wú)重復(fù)風(fēng)險(xiǎn)地重新執(zhí)行。新會(huì)話中的重新執(zhí)行要使用新的LTXID。如果其他的服務(wù)器在先前的會(huì)話中嘗試交付事務(wù)性命令集,那么其他的服務(wù)器就會(huì)檢測(cè)事務(wù)性命令集是否已被阻止以避免事務(wù)性命令集的重復(fù)執(zhí)行(也就是不可預(yù)測(cè)的輸出)。作為響應(yīng),其他的服務(wù)器會(huì)將已經(jīng)在該會(huì)話中根據(jù)事務(wù)性命令集做出的任何改變退回重來(lái)。[0075]在一個(gè)實(shí)施例中,服務(wù)器保持單次往返行程的事務(wù)例如使用自動(dòng)交付或嵌入在PL/SQL或Java中的那些事務(wù)的狀態(tài)或輸出。在從客戶端到服務(wù)器的單次請(qǐng)求中可以打開和關(guān)閉一項(xiàng)或多項(xiàng)事務(wù)。例如,客戶端可以調(diào)用PL/SQL過(guò)程或Java過(guò)程以在PL/SQL或Java模塊內(nèi)部的幾個(gè)不同的交付點(diǎn)向數(shù)據(jù)庫(kù)交付幾項(xiàng)不同的事務(wù)。如果交付了任何事務(wù),用于該LTXID的往返行程的輸出即被交付。當(dāng)交付被嵌入在模塊內(nèi),交付的輸出即被記錄為嵌入。當(dāng)交付是用于堆棧模塊的最后一次操作時(shí),交付可以被記錄或更新為完整交付。
[0076]在不同的實(shí)施例中,服務(wù)器存留遠(yuǎn)程事務(wù)和/或自主事務(wù)和/或呼出事務(wù)的輸出。
[0077]在一個(gè)實(shí)施例中,服務(wù)器存留用于PL/SQL、DDL和數(shù)據(jù)控制語(yǔ)言(“DCL”)命令的嵌入狀態(tài)或輸出。
[0078]在一個(gè)實(shí)施例中,服務(wù)器檢測(cè)命令集何時(shí)包括事務(wù)。在事務(wù)開始時(shí),服務(wù)器嘗試記錄LTXID作為事務(wù)的一部分。如果事務(wù)已開始或已交付或已被阻止,那么服務(wù)器就避免再次嘗試該項(xiàng)事務(wù)。如果事務(wù)已開始或已交付,那么服務(wù)器就阻止完成隨后的事務(wù)。如果當(dāng)前的服務(wù)器在完成或阻止事務(wù)時(shí)成功阻止了其他嘗試,那么服務(wù)器就可以嘗試完成事務(wù)而無(wú)需承擔(dān)事務(wù)完成多于一次的風(fēng)險(xiǎn)。
[0079]在另一個(gè)實(shí)施例中,服務(wù)器檢測(cè)命令集何時(shí)包括事務(wù)。在事務(wù)開始時(shí),服務(wù)器注冊(cè)LTXID以記錄在COMMIT作為事務(wù)的一部分。在COMMIT,如果事務(wù)已經(jīng)例如在另一個(gè)會(huì)話中被阻止,那么當(dāng)前的事務(wù)即被阻止而不得提交和退回重來(lái)。
[0080]在一個(gè)實(shí)施例中,即使數(shù)據(jù)庫(kù)恢復(fù)為較早版本或者在隨后的數(shù)據(jù)庫(kù)實(shí)體中出現(xiàn)故障,服務(wù)器也可以處理來(lái)自客戶端的事務(wù)序列。例如,服務(wù)器可以管理會(huì)話所用的LTXID以使交付序列單調(diào)增加,并且客戶端可以依賴于這種穩(wěn)定特性來(lái)確定已經(jīng)發(fā)送的事務(wù)性命令集所用的但是尚未收到其結(jié)果的LTXID。
[0081]在一個(gè)實(shí)施例中,服務(wù)器可以高頻地處理多項(xiàng)事務(wù),并在處理時(shí)記錄多項(xiàng)事務(wù)的輸出。例如,服務(wù)器可以在交付事務(wù)性命令集時(shí)更新每一個(gè)LTXID的交付編號(hào)而無(wú)需針對(duì)每一項(xiàng)事務(wù)創(chuàng)建新的LTXID。
[0082]在一個(gè)實(shí)施例中,服務(wù)器屏蔽了數(shù)據(jù)庫(kù)跟客戶端或終端用戶交流時(shí)涉及到的停機(jī)的沖擊。因?yàn)榉?wù)器存留了交付輸出,當(dāng)一臺(tái)服務(wù)器在執(zhí)行事務(wù)的時(shí)候經(jīng)歷停機(jī)時(shí),另一臺(tái)服務(wù)器就能夠獲知事務(wù)的輸出。服務(wù)器可以避免停機(jī)能夠以其他方式造成對(duì)用戶的可見(jiàn)沖擊、造成輸入數(shù)據(jù)丟失或者造成應(yīng)用程序或應(yīng)用程序組件的重啟,避免消耗可觀的時(shí)間和資源。服務(wù)器可以屏蔽停機(jī)和交流中斷而無(wú)需給應(yīng)用程序開發(fā)人員增加負(fù)擔(dān)。服務(wù)器軟件可以無(wú)重復(fù)風(fēng)險(xiǎn)地允許將請(qǐng)求在系統(tǒng)內(nèi)的其他服務(wù)器重試或安全地繼續(xù)。
[0083]獲知事務(wù)輸出可以得到改進(jìn)的終端用戶體驗(yàn)、更高的應(yīng)用程序可用性、改進(jìn)應(yīng)用程序開發(fā)人員處理停機(jī)的生產(chǎn)力并在服務(wù)器、中間層和應(yīng)用程序產(chǎn)品之間獲得更好的集成和協(xié)作。服務(wù)器的功能無(wú)需顯著改變應(yīng)用程序即可實(shí)現(xiàn)。服務(wù)器的功能可以在服務(wù)會(huì)由于停機(jī)而意外中斷的多種情況下避免中斷用戶服務(wù)。在一個(gè)示例中,服務(wù)器提供了在按計(jì)劃和意外停機(jī)以及重復(fù)提交的情況下用于最多執(zhí)行一次的語(yǔ)義的一般性架構(gòu)。服務(wù)器可以存留交付輸出,針對(duì)每一項(xiàng)事務(wù)提升已知的預(yù)期輸出,并且支持最多一次的事務(wù)執(zhí)行。
[0084]圖9示出了客戶端利用數(shù)據(jù)庫(kù)會(huì)話訪問(wèn)數(shù)據(jù)庫(kù)的示例性結(jié)構(gòu)。在示例中,客戶端902利用數(shù)據(jù)庫(kù)會(huì)話904A訪問(wèn)數(shù)據(jù)庫(kù)906。客戶端902可以隨后檢測(cè)數(shù)據(jù)庫(kù)會(huì)話904A的不可用性,并且不會(huì)丟失在客戶端一方的會(huì)話中建立的無(wú)法傳遞至數(shù)據(jù)庫(kù)會(huì)話904B的狀態(tài)。例如,客戶端902可以在會(huì)話904B重新運(yùn)行最初在會(huì)話904A執(zhí)行或請(qǐng)求執(zhí)行的命令。
[0085]在一個(gè)實(shí)施例中,即使命令不可能交付,服務(wù)器也可以提供關(guān)于命令是否被交付的指示。例如,客戶端可以請(qǐng)求命令集的輸出,即使該命令集被部分或全部執(zhí)行也不能完成事務(wù)。在通過(guò)阻止命令集強(qiáng)行設(shè)定輸出后,服務(wù)器可以通過(guò)指明命令集并未完成事務(wù)來(lái)答復(fù)請(qǐng)求,和/或服務(wù)器可以指明無(wú)論命令集是否完成該命令集都不可能完成事務(wù)。服務(wù)器還可以向客戶端指明在服務(wù)器一方關(guān)于命令集的進(jìn)程,其中明確了哪些命令已執(zhí)行或尚未執(zhí)行。
[0086]在一個(gè)實(shí)施例中,本應(yīng)響應(yīng)于命令集從服務(wù)器發(fā)送至客戶端的結(jié)果如果確實(shí)被發(fā)送則應(yīng)包括客戶端能夠依賴于客戶端一方操作的數(shù)值。如果客戶端針對(duì)尚未返回這種數(shù)值的命令請(qǐng)求輸出,那么即使在命令集中沒(méi)有尚未完成的事務(wù),客戶端也可以接收到命令尚未完成的指示。在接收到對(duì)命令輸出的請(qǐng)求之后,服務(wù)器可以確定結(jié)果本應(yīng)包括這樣的數(shù)值并且向客戶端指明命令集尚未完成,直到由客戶端接收到該數(shù)值為止。在執(zhí)行命令時(shí)本應(yīng)由服務(wù)器返回并且依賴于客戶端的數(shù)據(jù)可以有多種類型,包括事務(wù)跟蹤信息,在執(zhí)行命令時(shí)是否出現(xiàn)了任何錯(cuò)誤(并且可能是錯(cuò)誤列表),客戶端明確請(qǐng)求(根據(jù)選擇或輸出賦值返回)的其他數(shù)據(jù)和/或自動(dòng)返回的數(shù)據(jù)例如受命令影響的行號(hào)。其他類型的信息例如事務(wù)當(dāng)前是否打開可能并不依賴于客戶端,并且客戶端可能無(wú)法接收到該信息的事實(shí)并不能阻止服務(wù)器向客戶端指明命令集已經(jīng)完成。其他類型的信息盡管并未返回客戶端也仍然可以保存在數(shù)據(jù)庫(kù)內(nèi)以用于在新建立的會(huì)話中返回給客戶端。為了向客戶端指明命令集已經(jīng)完成,也可能并不需要保存的信息。
[0087]在一個(gè)實(shí)施例中,服務(wù)器可以將尚未返回給客戶端的結(jié)果返回。如果服務(wù)器在新建立的會(huì)話中返回客戶端本應(yīng)依賴的結(jié)果,那么即使是在先前的會(huì)話中并未范圍結(jié)果,月艮務(wù)器也可以隨后在新建立的會(huì)話中將命令集作為完成處理。
[0088]在一個(gè)實(shí)施例中,命令集可以包括對(duì)會(huì)話狀態(tài)做出明確改變的命令。例如,命令可以改變應(yīng)該用于會(huì)話的語(yǔ)言。如果客戶端針對(duì)改變會(huì)話狀態(tài)的命令請(qǐng)求輸出,那么如果該會(huì)話狀態(tài)未存留在數(shù)據(jù)庫(kù)內(nèi)則客戶端就可以接收命令尚未完成的指示。在接收對(duì)輸出的請(qǐng)求時(shí),服務(wù)器可以確定命令集本應(yīng)改變會(huì)話狀態(tài)并且直到在新建立的會(huì)話中對(duì)會(huì)話狀態(tài)實(shí)施了改變之前都向客戶端指明命令集仍未完成。
[0089]在一個(gè)實(shí)施例中,服務(wù)器可以對(duì)會(huì)話狀態(tài)實(shí)施尚未完成的改變。如果服務(wù)器在新建立的會(huì)話中實(shí)施本應(yīng)在先前的會(huì)話中若完成了命令就應(yīng)實(shí)現(xiàn)的改變,那么即使在先前的會(huì)話中并未實(shí)現(xiàn)改變服務(wù)器也可以在新建立的會(huì)話中將命令作為完成處理。
[0090]在一個(gè)實(shí)施例中,服務(wù)器可以跟蹤本應(yīng)通過(guò)在從客戶端到服務(wù)器的單次請(qǐng)求中提交的命令促使的多項(xiàng)事務(wù)。例如,服務(wù)器可以將基于針對(duì)命令的執(zhí)行計(jì)劃或者基于服務(wù)器已知用于促使事務(wù)的命令而預(yù)測(cè)要執(zhí)行的事務(wù)編號(hào)。用這種方式,即使單個(gè)命令集促使了多項(xiàng)事務(wù)也可以跟蹤針對(duì)每一項(xiàng)獨(dú)立事務(wù)的交付輸出。在本實(shí)施例中,服務(wù)器可以在針對(duì)包括多項(xiàng)事務(wù)的請(qǐng)求逐項(xiàng)事務(wù)處理的基礎(chǔ)上而不是在逐項(xiàng)請(qǐng)求處理的基礎(chǔ)上向客戶端提供事務(wù)輸出。在一個(gè)特定的示例中,客戶端可以針對(duì)請(qǐng)求來(lái)請(qǐng)求事務(wù)輸出,然后服務(wù)器可以通過(guò)提供用于多項(xiàng)事務(wù)的多個(gè)事務(wù)輸出來(lái)響應(yīng),如果請(qǐng)求被執(zhí)行完成就能促使或者就應(yīng)該促使所述的多項(xiàng)事務(wù)。服務(wù)器可以報(bào)告?zhèn)€別事務(wù)的完成而不是將全部事務(wù)作為整體來(lái)報(bào)告,并且服務(wù)器可以阻止個(gè)別未交付事務(wù)而不是將所有的未交付事務(wù)作為整體來(lái)阻止。通過(guò)由服務(wù)器阻止并報(bào)告未交付狀態(tài)來(lái)強(qiáng)行設(shè)定未交付狀態(tài)可以是對(duì)來(lái)自客戶端的識(shí)別促使了多項(xiàng)事務(wù)的命令集的信息請(qǐng)求的響應(yīng),或者通過(guò)識(shí)別命令集內(nèi)的特定事務(wù)來(lái)完成。
[0091]在一個(gè)實(shí)施例中,響應(yīng)于來(lái)自客戶端的關(guān)于通過(guò)LTXID識(shí)別出的事務(wù)的信息請(qǐng)求,服務(wù)器可以確定執(zhí)行由LTXID標(biāo)識(shí)的交易的過(guò)程已死、確保無(wú)法完成或者預(yù)測(cè)為無(wú)法完成。在一個(gè)示例中,服務(wù)器可以通過(guò)借助負(fù)責(zé)用于執(zhí)行由該LTXID標(biāo)識(shí)的交易的其他組件進(jìn)行校驗(yàn)來(lái)完成該確定。在本實(shí)施例中,即使服務(wù)器尚未阻止事務(wù),服務(wù)器也可以向客戶端報(bào)告事務(wù)已確保無(wú)法完成。
[0092]執(zhí)行事務(wù)性命令
[0093]一種示例性數(shù)據(jù)庫(kù)管理系統(tǒng)(DBMS)例如ORACLE、例如很多其他的DMBMS通過(guò)包括ORACLE的OCI驅(qū)動(dòng)程序和ORACLE的JDBC驅(qū)動(dòng)程序在內(nèi)的各種客戶端驅(qū)動(dòng)程序接口為應(yīng)用程序編寫人員提供了基于事務(wù)的編程模型。通過(guò)驅(qū)動(dòng)程序,頂層的SQL和PL/SQL調(diào)用建立起會(huì)話中的事務(wù)狀態(tài)和非事務(wù)狀態(tài)。在示例性系統(tǒng)中,客戶端驅(qū)動(dòng)程序向關(guān)系數(shù)據(jù)庫(kù)管理系統(tǒng)(RDBMS)發(fā)送 SELECT、PL/SQL、ALTER SESSION、DML 和 TRUNCATE 語(yǔ)句并且在事務(wù)結(jié)束時(shí)交付改變。交付可以在用于服務(wù)器的同一個(gè)往返行程內(nèi)進(jìn)行,或者也可以在單獨(dú)的往返行程內(nèi)進(jìn)行。
[0094]圖1更加詳細(xì)地示出了示例性系統(tǒng)中的不同組件和層。系統(tǒng)支持狀態(tài)構(gòu)建和交付處理。參照?qǐng)D1的工作流步驟,在登錄階段112,客戶端發(fā)出調(diào)用以跟數(shù)據(jù)庫(kù)系統(tǒng)104-110相連接。在登錄階段112,客戶端驅(qū)動(dòng)程序102完成認(rèn)證握手并且建立客戶端一方的會(huì)話句柄。在步驟116建立跟數(shù)據(jù)庫(kù)系統(tǒng)的連接。在無(wú)事務(wù)階段118,客戶端102在步驟120中向RDBMS SQL層106發(fā)送SQL和PL/SQL命令。在122階段,RDBMS SQL層106分析、關(guān)聯(lián)并執(zhí)行命令120。RDBMSSQL層106編譯每一條語(yǔ)句并向SQL引擎或PL/SQL引擎發(fā)送請(qǐng)求。在步驟124執(zhí)行命令120建立起用于會(huì)話的非事務(wù)性狀態(tài)。在步驟126,服務(wù)器向客戶端返回結(jié)果集合、輸出關(guān)聯(lián)、DML返回結(jié)果和ORACLE消息。這些結(jié)果的一部分被存留在客戶端驅(qū)動(dòng)程序內(nèi)并傳輸至應(yīng)用程序。
[0095]在有數(shù)據(jù)庫(kù)事務(wù)的階段128,客戶端102在步驟130向RDBMSSQL層106發(fā)送DML命令以及包含DML的PL/SQL命令。在132階段,RDBMS SQL層106分析、關(guān)聯(lián)并執(zhí)行命令130。SQL層編譯每一條語(yǔ)句并向PL/SQL引擎和DML驅(qū)動(dòng)程序發(fā)送請(qǐng)求。在步驟134執(zhí)行命令啟動(dòng)一項(xiàng)或多項(xiàng)事務(wù)并且在步驟136建立RDBMS事務(wù)層108處的會(huì)話狀態(tài)和事務(wù)狀態(tài)。DML操作結(jié)果或ORACLE出錯(cuò)信息在步驟138返回給客戶端102。
[0096]在交付工作階段140客戶端102發(fā)送交付請(qǐng)求或者已經(jīng)在步驟142設(shè)定包含對(duì)RDBMS SQL層106的請(qǐng)求的自動(dòng)交付。在交付階段144,RDBMS SQL層106編譯語(yǔ)句并且在步驟146向事務(wù)層發(fā)送交付請(qǐng)求。在刷新重做(flush redo)階段148, RDBMS事務(wù)層108在步驟150將改變記錄刷新至磁盤。RDBMS事務(wù)層108在步驟152在交付后的觸發(fā)程序中構(gòu)建成功的交付,并且促使交付后的觸發(fā)程序返回RDBMS SQL層。在步驟154,RDBMS SQL層106向客戶端102返回COMMIT消息。
[0097]在一個(gè)實(shí)施例中,客戶端在身份驗(yàn)證時(shí)、在校驗(yàn)時(shí)以及在每一次事務(wù)或事務(wù)性命令集成功交付時(shí)接收邏輯事務(wù)ID,此時(shí)要接收對(duì)事務(wù)性命令集的確認(rèn)。在一個(gè)實(shí)施例中,例如在前臺(tái)過(guò)程或數(shù)據(jù)庫(kù)實(shí)例崩潰或網(wǎng)絡(luò)故障或出現(xiàn)任何一種異常終止的情況時(shí),客戶端驅(qū)動(dòng)程序和DBMS之間就存在停機(jī)。客戶端接收出錯(cuò)信息并且服務(wù)器一方的事務(wù)性和非事務(wù)性狀態(tài)丟失。如果針對(duì)DBMS的最后一次通信是交付請(qǐng)求142或者可能包含交付請(qǐng)求,那么使用現(xiàn)有系統(tǒng)的應(yīng)用程序在應(yīng)用程序發(fā)送交付請(qǐng)求之后就無(wú)法獲得交付輸出。交付可能已經(jīng)完成或者也可能并未完成,這取決于停機(jī)出現(xiàn)在哪個(gè)位置。例如,因?yàn)椴僮骺赡苁窃诓樵冎罅⒖探桓?,所以?yīng)用程序可能不知道交付消息丟失與否,并且應(yīng)用程序無(wú)法安全查詢最后一次交付請(qǐng)求的輸出并恢復(fù)丟失的交付消息。
[0098]如果客戶端已經(jīng)進(jìn)入工作并且在停機(jī)之前將該工作提交至服務(wù)器,那么客戶端處的狀態(tài)在停機(jī)之后得以保持,可能具有輸入數(shù)據(jù)、返回?cái)?shù)據(jù)和緩存的變量。應(yīng)用程序需要以此運(yùn)行的非事務(wù)性會(huì)話狀態(tài)在現(xiàn)有的系統(tǒng)中丟失。如果事務(wù)已經(jīng)開始并且交付尚未發(fā)出,那么進(jìn)行中的事務(wù)就退回重來(lái)并且需要重新提交。如果事務(wù)已經(jīng)開始并且交付也已發(fā)出,那么送回客戶端的交付信息在現(xiàn)有的系統(tǒng)中無(wú)法持久。使用現(xiàn)有系統(tǒng)的客戶端變成無(wú)法獲知事務(wù)是否交付。
[0099]在現(xiàn)有的系統(tǒng)中,送回客戶端的交付信息無(wú)法持久。如果在客戶端和服務(wù)器之間有中斷,那么客戶端就會(huì)看到指示通信出錯(cuò)的錯(cuò)誤信息。這種報(bào)錯(cuò)不會(huì)告知應(yīng)用程序提交是否執(zhí)行了任何交付操作,或者過(guò)程調(diào)用是運(yùn)行完成了所有預(yù)期交付的執(zhí)行和會(huì)話狀態(tài)的改變還是中途出錯(cuò)或者甚至是在從客戶端斷開后仍保持運(yùn)行。
[0100]應(yīng)用程序開發(fā)人員可以寫入自定義代碼以在停機(jī)之后重新連接,但是應(yīng)用程序沒(méi)有用于將停機(jī)之間建立起來(lái)的非事務(wù)性會(huì)話狀態(tài)重新建立或者嘗試測(cè)試服務(wù)器以確定提交的工作是否交付或需要重復(fù)的機(jī)制。任何代碼模塊都有可能出錯(cuò),并且應(yīng)用程序開發(fā)人員不能在每一個(gè)交付點(diǎn)都執(zhí)行這種形式的錯(cuò)誤處理以確定指定的事務(wù)是否交付以及要恢復(fù)哪些狀態(tài)以繼續(xù)。應(yīng)用程序可以利用應(yīng)用程序和服務(wù)器之間的附加帶寬寫入修改編號(hào)或存儲(chǔ)其他的一致信息以備能夠查詢。使用這些附加帶寬是不合需要的,并且存留修改編號(hào)在按年月日排序方面以及在有故常而重定向至不同的數(shù)據(jù)庫(kù)時(shí)也不安全。在沒(méi)有主關(guān)鍵字或修改編號(hào)時(shí),應(yīng)用程序無(wú)法為了改變-跟蹤而進(jìn)行查詢并且查詢自身的方法是有根本缺陷的,原因是查詢的內(nèi)容可能在查詢之后立刻交付。另外,對(duì)于提交包含多次交付的工作的批次管理程序,如果工作并未存留若重新提交就重啟的位置記錄,那么工作的重新提交就是不可行的。
[0101]通過(guò)應(yīng)用跟蹤應(yīng)用程序的數(shù)據(jù)而提交的查詢無(wú)法披露事務(wù)是否已經(jīng)完成,原因是事務(wù)可能在該查詢執(zhí)行之后立刻交付。實(shí)際上,在通信出錯(cuò)之后,服務(wù)器仍然可能運(yùn)行提交而并未意識(shí)到客戶端已斷開。對(duì)于PL/SQL或Java命令,沒(méi)有用于過(guò)程提交的關(guān)于提交是運(yùn)行完成還是中途異常終止的記錄。盡管過(guò)程中的命令可能已經(jīng)交付,但是針對(duì)該過(guò)程的后續(xù)工作可能仍未完成。
[0102]應(yīng)用程序也不能跟蹤本地事務(wù)、遠(yuǎn)程事務(wù)、分布式事務(wù)、并行事務(wù)、重復(fù)事務(wù)和XA事務(wù)。即使應(yīng)用程序在特定的情況下能夠確定在特定故障之前要執(zhí)行哪些命令,重建在應(yīng)用程序生存期內(nèi)建立起來(lái)的非事務(wù)性會(huì)話狀態(tài)對(duì)于在運(yùn)行時(shí)修改非事務(wù)性會(huì)話的應(yīng)用程序來(lái)說(shuō)也并不簡(jiǎn)單。
[0103]無(wú)法識(shí)別出最后一次提交是已經(jīng)交付還是應(yīng)該在隨后的某一時(shí)刻交付還是并未運(yùn)行完成能夠由于用戶和軟件可能嘗試重新發(fā)起已經(jīng)存留的改變而導(dǎo)致重復(fù)的事務(wù)提交和其他形式的“邏輯訛誤”。
[0104]如果丟失的會(huì)話被再次提交,那么只要系統(tǒng)允許,重新提交就能夠保持原子性和一致性。但是,如果針對(duì)事務(wù)建立的非事務(wù)性狀態(tài)不正確或者如果事務(wù)已經(jīng)交付,那么事務(wù)就不能被準(zhǔn)確地重新提交。在現(xiàn)有的系統(tǒng)中,服務(wù)器和客戶端之間的讀操作沒(méi)有冪等性。在缺少冪等性的情況下,重新提交能夠?qū)е率聞?wù)的應(yīng)用多于一次。
[0105]檢測(cè)數(shù)據(jù)庫(kù)會(huì)話的不可用性或超時(shí)
[0106]作為一個(gè)示例,客戶端可以在客戶端從用于在會(huì)話中執(zhí)行的最新命令集接收結(jié)果之前或之后檢測(cè)數(shù)據(jù)庫(kù)會(huì)話的不可用性或超時(shí)。在一個(gè)實(shí)施例中,在客戶端發(fā)送用于在數(shù)據(jù)庫(kù)會(huì)話中執(zhí)行的命令集之后,客戶端才接收到數(shù)據(jù)庫(kù)會(huì)話已無(wú)效的通知。作為響應(yīng),無(wú)論命令集是否執(zhí)行,客戶端都可以嘗試阻止命令集??蛻舳丝梢钥蛇x地嘗試在新的數(shù)據(jù)庫(kù)會(huì)話中重新運(yùn)行命令集。如果客戶端選擇在新的數(shù)據(jù)庫(kù)會(huì)話中重新運(yùn)行命令集,那么提供新數(shù)據(jù)庫(kù)會(huì)話的服務(wù)器即可避免事務(wù)重復(fù)。例如,服務(wù)器可以避免重新執(zhí)行已經(jīng)在初始對(duì)話中執(zhí)行過(guò)的命令。服務(wù)器也可以在新會(huì)話中重新運(yùn)行事務(wù)之前阻止事務(wù)的執(zhí)行。
[0107]在一個(gè)實(shí)施例中,監(jiān)測(cè)邏輯接收指示數(shù)據(jù)庫(kù)會(huì)話以變?yōu)閼?yīng)用程序不可用的信息。例如,信息可以指示數(shù)據(jù)庫(kù)實(shí)例已出錯(cuò)或就要出錯(cuò),或者由數(shù)據(jù)庫(kù)示例提供給應(yīng)用程序的服務(wù)或其他資源已出錯(cuò)或就要出錯(cuò)。作為另一個(gè)示例,信息可以指示數(shù)據(jù)庫(kù)實(shí)例已經(jīng)無(wú)法在至少閾值時(shí)間量?jī)?nèi)做出響應(yīng)(也就是說(shuō)實(shí)例已超時(shí))。數(shù)據(jù)庫(kù)會(huì)話的不可用性可以緣于計(jì)劃內(nèi)或意外的停機(jī)。對(duì)于計(jì)劃內(nèi)停機(jī),即使數(shù)據(jù)庫(kù)會(huì)話可能仍然可用,由監(jiān)測(cè)邏輯接收的信息也指示停機(jī)是計(jì)劃內(nèi)的。指示計(jì)劃內(nèi)的“宕機(jī)”或停機(jī)允許在會(huì)話出故障和恢復(fù)之前完成工作。實(shí)際上,在使用連接池時(shí),如果所有工作已完成,因?yàn)閼?yīng)用程序請(qǐng)求已經(jīng)完成,所以就不需要恢復(fù)會(huì)話。相反,如果使用指定會(huì)話,重新運(yùn)行就將會(huì)話轉(zhuǎn)移至另一個(gè)實(shí)例以允許計(jì)劃內(nèi)的停機(jī)。在一個(gè)實(shí)施例中,數(shù)據(jù)庫(kù)實(shí)例可以實(shí)現(xiàn)為對(duì)一種服務(wù)不可用但是對(duì)另一種服務(wù)可用,目的是為了降低數(shù)據(jù)庫(kù)系統(tǒng)內(nèi)的實(shí)例負(fù)荷。監(jiān)測(cè)邏輯可以從記錄原始數(shù)據(jù)庫(kù)會(huì)話可用性的任何代理程序或組件接收信息。監(jiān)測(cè)邏輯可以通過(guò)關(guān)閉數(shù)據(jù)庫(kù)會(huì)話(例如由不可用數(shù)據(jù)庫(kù)實(shí)例服務(wù)的會(huì)話)、打開新的數(shù)據(jù)庫(kù)會(huì)話(例如由新的數(shù)據(jù)庫(kù)實(shí)例服務(wù)的會(huì)話)并且在新的數(shù)據(jù)庫(kù)會(huì)話中促使重新運(yùn)行先前在現(xiàn)已不可用的數(shù)據(jù)庫(kù)會(huì)話中發(fā)送的命令而對(duì)信息做出響應(yīng)。在以這種方式用于“分配”工作時(shí),重新運(yùn)行應(yīng)該位于負(fù)荷較小的數(shù)據(jù)庫(kù)實(shí)例。
[0108]在一個(gè)實(shí)施例中,監(jiān)測(cè)邏輯每一次檢查數(shù)據(jù)庫(kù)會(huì)話是否可用,應(yīng)用程序都提交用于在數(shù)據(jù)庫(kù)會(huì)話中執(zhí)行的命令。因此,檢測(cè)數(shù)據(jù)庫(kù)會(huì)話是否已變?yōu)椴豢捎每梢噪S著接收要在數(shù)據(jù)庫(kù)會(huì)話中執(zhí)行的命令而同步進(jìn)行。如果接口關(guān)閉那這種技術(shù)就可供使用。如果節(jié)點(diǎn)或網(wǎng)絡(luò)故障,那么直到保持有效的TCP/IP過(guò)期之后才能接收到錯(cuò)誤。
[0109]在一個(gè)實(shí)施例中,用于監(jiān)測(cè)的有效技術(shù)是跟命令異步地接收快速應(yīng)用程序通知(“FAN”)事件。FAN事件無(wú)論會(huì)話是否可用都有助于消除報(bào)廢代碼的路徑校驗(yàn)并消除等待有效TCP的需求。
[0110]FAN監(jiān)測(cè)邏輯訂制向訂購(gòu)者發(fā)布可用性信息的服務(wù)。例如,監(jiān)測(cè)邏輯可以在快速應(yīng)用程序通知(“FAN”)事件中接收更新信息。通過(guò)快速通知借此公布很多事件用于系統(tǒng)狀態(tài)變化的改變,應(yīng)用程序就能夠快速恢復(fù)并且會(huì)話也能夠快速地重新平衡。在跟服務(wù)相關(guān)聯(lián)的資源經(jīng)歷輸出改變例如終止或啟動(dòng)/重啟時(shí),通知事件被立刻公布以供該事件的各種訂購(gòu)者使用。例如,通知事件在數(shù)據(jù)庫(kù)實(shí)例變?yōu)榭捎没虿豢捎脮r(shí)或者在實(shí)例中的服務(wù)變?yōu)榭捎没虿豢捎脮r(shí)發(fā)出。通知事件包含使訂購(gòu)者能夠根據(jù)匹配會(huì)話簽名來(lái)識(shí)別受輸出改變影響的特定會(huì)話的信息并由此做出響應(yīng)。這就允許在資源無(wú)效時(shí)快速地放棄會(huì)話并快速終止正在進(jìn)行的處理,還允許在資源重啟時(shí)快速地重新平衡工作。
[0111]通知事件針對(duì)用于服務(wù)以及支持服務(wù)的資源例如特定實(shí)例、實(shí)例、節(jié)點(diǎn)或數(shù)據(jù)庫(kù)集群的輸出改變而出現(xiàn)。在由一個(gè)或多個(gè)實(shí)例提供的服務(wù)開始時(shí),發(fā)出可以用于啟動(dòng)依賴于該服務(wù)的應(yīng)用程序的通知事件(UP)。在由一個(gè)或多個(gè)實(shí)例提供的服務(wù)終止時(shí),還有在實(shí)例、節(jié)點(diǎn)或網(wǎng)絡(luò)終止時(shí),發(fā)出停止相關(guān)應(yīng)用程序的通知事件(DOWN)。在管理集群軟件因?yàn)榉?wù)已經(jīng)超過(guò)其故障閾值而不能再管理服務(wù)時(shí),發(fā)出中斷重試服務(wù)的應(yīng)用程序的通知事件(NOT_RESTARTING)。在一個(gè)實(shí)施例中,NOT_RESTARTING事件啟動(dòng)到災(zāi)難服務(wù)的切換。
[0112]在連接至集群之后,唯一性的簽名(也就是定位器)被生成用于相關(guān)會(huì)話并記錄在句柄上作為連接的一部分。在一個(gè)實(shí)施例中,簽名包括服務(wù)標(biāo)識(shí)符、節(jié)點(diǎn)標(biāo)識(shí)符以及數(shù)據(jù)庫(kù)唯一名稱和實(shí)例標(biāo)識(shí)符,其中的每一個(gè)都跟會(huì)話相關(guān)聯(lián)。在數(shù)據(jù)庫(kù)集群的背景下,通知事件包含使訂購(gòu)者能夠識(shí)別受輸出改變影響的特定會(huì)話的信息也就是受影響會(huì)話的簽名。對(duì)于某些事件類型,用于識(shí)別受影響會(huì)話的信息包括跟輸出改變相關(guān)聯(lián)的服務(wù)和數(shù)據(jù)庫(kù)的標(biāo)識(shí)符。對(duì)于另一些事件類型,用于識(shí)別受影響會(huì)話的信息還包括跟輸出改變相關(guān)聯(lián)的實(shí)例和節(jié)點(diǎn)的標(biāo)識(shí)符。受影響的會(huì)話是簽名跟事件有效負(fù)載內(nèi)包含的簽名相匹配的會(huì)話。
[0113]在各種實(shí)例中,檢測(cè)之后存在不同的能夠開始重新運(yùn)行的時(shí)間點(diǎn)。監(jiān)測(cè)邏輯可以從FAN事件接收信息,清除無(wú)效會(huì)話,但是并不立刻啟動(dòng)重新運(yùn)行。例如,在接收到在已知要成為不可用的會(huì)話中執(zhí)行的命令后,驅(qū)動(dòng)程序建立新會(huì)話,在其中重建針對(duì)先前不可用會(huì)話而存在的客戶端狀態(tài)。在另一個(gè)實(shí)施例中,驅(qū)動(dòng)程序可以響應(yīng)于檢測(cè)到不可用性而啟動(dòng)重新運(yùn)行。
[0114]在一個(gè)實(shí)例中,監(jiān)測(cè)邏輯響應(yīng)于接收到要在已經(jīng)變?yōu)椴豢捎玫臄?shù)據(jù)庫(kù)會(huì)話中執(zhí)行的命令而觸發(fā)在可用的數(shù)據(jù)庫(kù)會(huì)話中重新運(yùn)行。在本實(shí)施例中,監(jiān)測(cè)邏輯可以檢測(cè)到數(shù)據(jù)庫(kù)會(huì)話已變?yōu)椴豢捎枚鵁o(wú)需恢復(fù)數(shù)據(jù)庫(kù)會(huì)話。例如,在數(shù)據(jù)庫(kù)會(huì)話已變?yōu)椴豢捎弥螅绻麤](méi)有更多的命令在該數(shù)據(jù)庫(kù)會(huì)話中執(zhí)行,那么就沒(méi)有必要重新運(yùn)行。在一個(gè)實(shí)施例中,監(jiān)測(cè)邏輯通過(guò)FAN或接收到的錯(cuò)誤獲知會(huì)話不可用。如果存在運(yùn)行中的命令那就調(diào)用重新運(yùn)行,或者如果沒(méi)有運(yùn)行中的命令,那就在應(yīng)用程序發(fā)送下一條命令時(shí)調(diào)用重新運(yùn)行。如果應(yīng)用程序再也不發(fā)送命令,那么重新運(yùn)行就不會(huì)發(fā)生。
[0115]在另一個(gè)實(shí)例中,重新運(yùn)行邏輯在接收到要在不可用的數(shù)據(jù)庫(kù)會(huì)話中執(zhí)行命令之前就觸發(fā)在可用的數(shù)據(jù)庫(kù)會(huì)話中重新運(yùn)行。用這種方式,數(shù)據(jù)庫(kù)會(huì)話可以在應(yīng)用程序?qū)?shù)據(jù)庫(kù)會(huì)話提交任何其他的命令之前就得到恢復(fù)。在接收到要在數(shù)據(jù)庫(kù)會(huì)話中執(zhí)行的另一條命令后,監(jiān)測(cè)邏輯應(yīng)該已經(jīng)促使重新運(yùn)行開始或完成以恢復(fù)數(shù)據(jù)庫(kù)會(huì)話。因此,新接收到的命令由于只需會(huì)話即可重新運(yùn)行而能更加高效地運(yùn)行。
[0116]存留邏輯事務(wù)標(biāo)識(shí)符(“LTXID”)
[0117]邏輯事務(wù)ID是全局唯一的ID,從應(yīng)用程序的角度唯一性地定義了數(shù)據(jù)庫(kù)會(huì)話。邏輯事務(wù)ID被存儲(chǔ)在OCI會(huì)話句柄以及用于瘦JDBC驅(qū)動(dòng)程序的連接對(duì)象內(nèi)。邏輯事務(wù)ID是冪等性語(yǔ)義的基礎(chǔ)。
[0118]用戶通過(guò)數(shù)據(jù)庫(kù)服務(wù)連接。為了實(shí)現(xiàn)最多執(zhí)行一次的語(yǔ)義而向服務(wù)定義中加入新屬性。該屬性被稱作commitjutcome。如果針對(duì)服務(wù)設(shè)定了該屬性那就要?jiǎng)?chuàng)建邏輯事務(wù)ID ;否則就要存留pre-12c特性。以下的說(shuō)明介紹了用于創(chuàng)建和存留邏輯事務(wù)ID的示例性步驟。
[0119]應(yīng)用程序通過(guò)對(duì)應(yīng)的驅(qū)動(dòng)程序連接至數(shù)據(jù)庫(kù)。在驅(qū)動(dòng)程序連接至數(shù)據(jù)庫(kù)時(shí)就啟動(dòng)新的數(shù)據(jù)庫(kù)會(huì)話。作為會(huì)話創(chuàng)建的一部分還創(chuàng)建了新的邏輯事務(wù)ID(LTXID)。邏輯事務(wù)ID僅創(chuàng)建并存儲(chǔ)在內(nèi)存中的用戶會(huì)話結(jié)構(gòu)內(nèi)并隨后返回給客戶端驅(qū)動(dòng)程序。邏輯事務(wù)ID尚未存儲(chǔ)在事務(wù)歷史表內(nèi)。新的邏輯事務(wù)ID被返回給驅(qū)動(dòng)程序并且用戶能夠查詢會(huì)話句柄已獲取邏輯事務(wù)ID的值。邏輯事務(wù)ID以交付編號(hào)O開始。如果僅僅讀取,那么LTXID不會(huì)改變。這是例如有效數(shù)據(jù)保護(hù)和只讀數(shù)據(jù)庫(kù)的情況。
[0120]如果應(yīng)用程序使用連接池,那么連接池已經(jīng)在服務(wù)器端和客戶端的會(huì)話中存留了邏輯事務(wù)ID (LTXID)。在從池中校驗(yàn)時(shí),應(yīng)用程序使用會(huì)話中經(jīng)其校驗(yàn)過(guò)的LTXID。該LTXID在最后一次登記時(shí)將交付編號(hào)返回連接池。
[0121]在一種示例性方法中,服務(wù)器接收用于在會(huì)話中執(zhí)行的命令集。服務(wù)器會(huì)話已經(jīng)存留了在身份驗(yàn)證時(shí)傳輸給客戶端或者客戶端在校驗(yàn)時(shí)包含的LTXID。一條或多條命令的集合如果在會(huì)話中完成就會(huì)促使執(zhí)行:啟動(dòng)事務(wù)的第一服務(wù)器操作和交付事務(wù)的第二服務(wù)器操作。在該實(shí)例中,服務(wù)器確定命令集中是否包括至少一條如果執(zhí)行就會(huì)啟動(dòng)至少一項(xiàng)事務(wù)的命令。響應(yīng)于確定命令集包括至少一條如果執(zhí)行就會(huì)啟動(dòng)至少一項(xiàng)事務(wù)的命令,月艮務(wù)器更新用于LTXID的存儲(chǔ)信息作為交付操作的一部分。在一個(gè)實(shí)例中,服務(wù)器執(zhí)行的服務(wù)器操作包括交付改變以及向事務(wù)歷史表中插入或更新存儲(chǔ)信息已指示命令集中的至少一項(xiàng)事務(wù)已經(jīng)利用該LTXID交付。在交付后,新的LTXID生成并且在用于交付信息的返程中返回給客戶端。
[0122]在一個(gè)實(shí)施例中,服務(wù)器存儲(chǔ)的事務(wù)歷史表包括用于會(huì)話中接收到的多個(gè)事務(wù)性命令集中的每一個(gè)事務(wù)性命令集的表項(xiàng)。服務(wù)器可以通過(guò)向用于命令集的事務(wù)歷史表中增加表項(xiàng)來(lái)更新存儲(chǔ)的信息以指示事務(wù)已經(jīng)在命令集中開始。
[0123]圖14示出了用于存留事務(wù)性命令集記錄的示例性方法。在步驟1402,服務(wù)器接收用于在會(huì)話中執(zhí)行的命令集。例如,服務(wù)器可以接收命名由服務(wù)器執(zhí)行的一條或多條命令的序列的請(qǐng)求。在步驟1404,服務(wù)器確定命令集中的命令如果執(zhí)行那是否會(huì)啟動(dòng)至少一項(xiàng)事務(wù)。如果命令并未啟動(dòng)事務(wù),那么服務(wù)器就在步驟1406確定命令集是否包括任何其他的命令。如果答案為是,那么服務(wù)器就針對(duì)第二條命令重新執(zhí)行步驟1404。如果服務(wù)器從未收到啟動(dòng)事務(wù)的命令,那么在步驟1408服務(wù)器就完成命令集的執(zhí)行而無(wú)需注冊(cè)或更新命令集所用的事務(wù)性信息例如LTXID。在另一個(gè)實(shí)施例中,即使命令集中沒(méi)有事務(wù),服務(wù)器也存儲(chǔ)對(duì)LTXID的臨時(shí)更新,但是除非服務(wù)器檢測(cè)到事務(wù)或者要執(zhí)行的潛在事務(wù),否則臨時(shí)更新并不交付。
[0124]另一方面,如果服務(wù)器確定命令集中的下一條命令若執(zhí)行就會(huì)啟動(dòng)事務(wù),那么服務(wù)器就在步驟1410注冊(cè)成若該事務(wù)交付就要記錄LTXID。服務(wù)器繼續(xù)執(zhí)行命令集,直到在步驟1412交付了開啟的事務(wù)為止。在交付時(shí),如果LTXID是第一次被看到,那就插入該LTXID0否則就更新LTXID。在一個(gè)實(shí)施例中,服務(wù)器在每一次交付時(shí)利用更新的LTXID記錄命令集內(nèi)的每一項(xiàng)交付事務(wù)。在另一個(gè)實(shí)施例中,服務(wù)器僅記錄命令集中是否存在至少一項(xiàng)交付的事務(wù)。在交付開啟的事務(wù)后,服務(wù)器在步驟1414插入或更新LTXID以指示開啟的事務(wù)已交付。在交付后,在步驟1416生成下一個(gè)要使用的LTXID并返回至客戶端。
[0125]邏輯事務(wù)標(biāo)識(shí)符(“LTXID”)唯一地定義了事務(wù)性命令集并且用于確定是否交付了最后一項(xiàng)事務(wù)并且如果確已交付那么交付是否已完成。邏輯事務(wù)標(biāo)識(shí)符可以包括用于數(shù)據(jù)庫(kù)和實(shí)例的特有域,目的是為了檢測(cè)故障是針對(duì)相同還是不同的數(shù)據(jù)庫(kù)。包含這種域的邏輯事務(wù)標(biāo)識(shí)符被稱作“全局唯一”。接下來(lái)要使用的邏輯事務(wù)標(biāo)識(shí)符由服務(wù)器端存留在每一個(gè)服務(wù)器端的會(huì)話中。事務(wù)標(biāo)識(shí)符還可以包括用于實(shí)例、會(huì)話、版本和/或服務(wù)的特有域。在一個(gè)實(shí)例中,邏輯事務(wù)標(biāo)識(shí)符被傳輸至并存留或儲(chǔ)存在Oracle?調(diào)用接口(“0CI”)會(huì)話句柄或ODBC或ODP.Net會(huì)話句柄或者來(lái)自瘦Java?數(shù)據(jù)庫(kù)互連(“JDBC”)驅(qū)動(dòng)程序的連接對(duì)象內(nèi)??蛻舳舜媪舴?wù)器計(jì)劃要使用的下一個(gè)邏輯事務(wù)ID的副本。
[0126]在一個(gè)實(shí)施例中,系統(tǒng)根據(jù)邏輯事務(wù)標(biāo)識(shí)符阻避免事務(wù)的重復(fù)執(zhí)行。重復(fù)執(zhí)行可以在交付時(shí)進(jìn)行檢測(cè)。在本實(shí)施例中的每一個(gè)交付點(diǎn),如果事務(wù)已經(jīng)交付就會(huì)違反服務(wù)器內(nèi)的約束條件校驗(yàn)。如果是這種情況,那就放棄交付并且將事務(wù)退回重來(lái)。如果不是這種情況,交付就繼續(xù)進(jìn)行。允許交付繼續(xù)進(jìn)行就阻止了利用相同的LTXID交付事務(wù)的后續(xù)嘗試。LTXID可以在交付時(shí)存儲(chǔ)或更新。在交付之后,服務(wù)器計(jì)劃針對(duì)該會(huì)話使用的下一個(gè)LTXID的副本被返回給客戶端。
[0127]在停機(jī)后,客戶端能夠連接至服務(wù)器。然后使用來(lái)自先前連接的LTXID就能測(cè)試最后一項(xiàng)事務(wù)的輸出。如果該事務(wù)并未交付,那么服務(wù)器可以阻止該LTXID以禁止使用該LTXID的在重新運(yùn)行之前激活的先前運(yùn)行中事務(wù)交付。如果LTXID已經(jīng)交付或者如果LTXID先前被阻止,那么阻止LTXID的嘗試可能會(huì)失敗。
[0128]在一個(gè)實(shí)施例中,用于會(huì)話的當(dāng)前LTXID描述了要在會(huì)話中交付的下一項(xiàng)事務(wù)。當(dāng)前的LTXID可以已某種可預(yù)測(cè)的方式例如通過(guò)遞加先前的LTXID來(lái)根據(jù)先前的LTXID計(jì)算。在服務(wù)器向客戶端發(fā)送跟先前LTXID相關(guān)聯(lián)的事務(wù)已交付的通知時(shí),服務(wù)器向客戶端輸送服務(wù)器計(jì)劃使用的下一個(gè)LTXID。
[0129]在一個(gè)實(shí)施例中,LTXID包括:
[0130]?版本
[0131]?數(shù)據(jù)庫(kù)標(biāo)識(shí)符
[0132]包括用于統(tǒng)一數(shù)據(jù)庫(kù)的可插入數(shù)據(jù)庫(kù)標(biāo)識(shí)符
[0133]?數(shù)據(jù)庫(kù)實(shí)例標(biāo)識(shí)符
[0134]?邏輯會(huì)話編號(hào)(⑶ID)
[0135].交付編號(hào)
[0136]?服務(wù)器標(biāo)識(shí)符
[0137]在各種實(shí)施例中,LTXID可以被用于針對(duì)以下情況支持最多執(zhí)行一次的語(yǔ)義:
[0138]本地事務(wù)
[0139]自主事務(wù)
[0140]交付成功(自動(dòng)交付)
[0141]只讀性事務(wù)
[0142]循環(huán)性事務(wù)
[0143]分布式和遠(yuǎn)程事務(wù)
[0144]并行DML
[0145]作業(yè)調(diào)度事務(wù)
[0146]XA 事務(wù)[0147]邏輯會(huì)話編號(hào)(GUID)在會(huì)話建立時(shí)自動(dòng)分配。在一個(gè)實(shí)施例中,GUID是應(yīng)用程序無(wú)法讀取的不透明結(jié)構(gòu)。在一個(gè)實(shí)施例中,GUID針對(duì)事務(wù)歷史的有效期是唯一的。
[0148]在一個(gè)實(shí)施例中,為了可量測(cè)性,運(yùn)行的交付編號(hào)在交付數(shù)據(jù)庫(kù)事務(wù)時(shí)增加。對(duì)于事務(wù)管理程序例如WebLogic來(lái)說(shuō)可以明確一種附加屬性。該屬性被用于WebLogic服務(wù)器或Tuxedo或其他事務(wù)管理程序自身的全局事務(wù)標(biāo)識(shí)符(“GTRID”)并且通常能夠用于描述XA事務(wù)。
[0149]在一個(gè)實(shí)施例中,邏輯事務(wù)ID消除了重復(fù)事務(wù)的可能性。利用邏輯事務(wù)ID消除重復(fù)事務(wù)的可能性被稱作自動(dòng)事務(wù)冪等性。邏輯事務(wù)ID在交付時(shí)存留并且在退回重來(lái)后重新使用。在正常運(yùn)行期間,LTXID被自動(dòng)存留在客戶端和服務(wù)器處用于每一項(xiàng)數(shù)據(jù)庫(kù)事務(wù)的會(huì)話中。在交付時(shí),邏輯事務(wù)ID被存留作為交付事務(wù)的一部分。
[0150]在一個(gè)實(shí)施例中,為了支持最多一次的協(xié)議,RDBMS在同意用于重試的存留期內(nèi)存留邏輯事務(wù)ID。默認(rèn)存留期是24小時(shí)。客戶可以選擇將該時(shí)段擴(kuò)展至一周或更長(zhǎng),或者根據(jù)需要縮短該時(shí)段。存留期越長(zhǎng),利用舊LTXID阻止舊會(huì)話以免重新運(yùn)行的最多一次的校驗(yàn)就持續(xù)得越長(zhǎng)。在調(diào)用多個(gè)RDBMS時(shí),就像在使用Data Guard和Golden Gate的情況,邏輯事務(wù)ID被復(fù)制到調(diào)用的每一個(gè)數(shù)據(jù)庫(kù)。
[0151]在一個(gè)示例中,為12c ORACLE JDBC(瘦且為0CI)和OCI客戶端提供的getLTXIDAPI允許應(yīng)用程序擁有檢索該會(huì)話要使用的下一個(gè)邏輯事務(wù)ID的能力。GET_LTXID_OUTCOME PL/SQL程序包允許應(yīng)用程序利用獲取的邏輯事務(wù)ID確定動(dòng)作的輸出。GET_LTXID_0UTC0ME程序包可以包括阻止LTXID免于交付以使得例如在使用該LTXID的事務(wù)運(yùn)行中時(shí)輸出是已知的。GET_LTXID_0UTC0ME在嘗試重新運(yùn)行之前調(diào)用并且可供各種應(yīng)用使用以包含在它們的應(yīng)用程序中。如本文所用,GET_LTXID_0UTC0ME和F0RCE_0UTC0ME能夠可互換地使用以供引用具有該功能的程序包。在一個(gè)實(shí)施例中,封裝返回事務(wù)是否交付、事務(wù)是不是完整的用戶調(diào)用以及LTXID是否被阻止。
[0152]在一個(gè)實(shí)施例中,邏輯事務(wù)標(biāo)識(shí)符到數(shù)據(jù)庫(kù)事務(wù)的映射被存留在事務(wù)歷史表內(nèi)。對(duì)于指定的會(huì)話,在服務(wù)器執(zhí)行會(huì)話中命令集內(nèi)的COMMIT或最后一次COMMIT時(shí),服務(wù)器可以插入若為第一次使用的LTXID或者更新當(dāng)前的LTXID。插入或更新被存儲(chǔ)在事務(wù)歷史表內(nèi),在停機(jī)情況下可供其他的會(huì)話和服務(wù)器使用。
[0153]在一個(gè)實(shí)施例中,服務(wù)器在事務(wù)開啟時(shí)執(zhí)行回調(diào)以創(chuàng)建或更新LTXID。服務(wù)器在生成重做(redo)時(shí)插入第一次的取值,并且服務(wù)器以可預(yù)測(cè)的方式更新隨后的取值。服務(wù)器在交付時(shí)也可以執(zhí)行回調(diào)以創(chuàng)建或更新LTXID。在磁盤上的redo穩(wěn)定之后,服務(wù)器可以將LTXID內(nèi)的交付編號(hào)加一或者用某種其他的可預(yù)測(cè)或確定性的方式來(lái)更新交付編號(hào)。服務(wù)器可以在會(huì)話句柄上將交付編號(hào)的增量或其他更新跟交付輸出一起返回。
[0154]在一個(gè)實(shí)施例中,用戶連接至數(shù)據(jù)庫(kù)并創(chuàng)建新的數(shù)據(jù)庫(kù)會(huì)話。如果跟用戶會(huì)話相關(guān)聯(lián)的數(shù)據(jù)庫(kù)服務(wù)具有“commitjutcome”屬性設(shè)置,那就針對(duì)該會(huì)話創(chuàng)建新的邏輯事務(wù)ID(LTXID)。例如,RDBMS內(nèi)核調(diào)用創(chuàng)建LTXID函數(shù)以將創(chuàng)建新的邏輯事務(wù)ID作為創(chuàng)建新的用戶會(huì)話的一部分。邏輯事務(wù)ID此時(shí)僅存儲(chǔ)在內(nèi)存中而尚未存留。LTXID通過(guò)會(huì)話句柄返回給客戶端。邏輯事務(wù)ID是唯一的,并且在同一集群或全局結(jié)構(gòu)的數(shù)據(jù)庫(kù)集合中的不同數(shù)據(jù)庫(kù)實(shí)例上不能創(chuàng)建相同的邏輯事務(wù)ID。
[0155]在一個(gè)實(shí)施例中,LTXID僅針對(duì)處理SQL的用戶會(huì)話創(chuàng)建。它們并不針對(duì)后臺(tái)會(huì)話創(chuàng)建。它們并不針對(duì)由任務(wù)使用的從屬過(guò)程例如內(nèi)存監(jiān)測(cè)程序(“MMON”)創(chuàng)建。在用于并行DML的實(shí)例中,只有并行協(xié)調(diào)程序具有相關(guān)聯(lián)的LTXID。在用于作業(yè)調(diào)度程序的實(shí)例中,LTXID被管理用于在作業(yè)調(diào)度從屬程序中運(yùn)行的作業(yè)。
[0156]在一個(gè)實(shí)施例中,LTXID僅在使用支持LTXID的客戶端時(shí)創(chuàng)建。支持LTXID的示例性客戶端包括OC1、瘦JDBC和JDBC0C1、OCCI以及ODP.Net客戶端。通過(guò)在會(huì)話所連接的服務(wù)上設(shè)置所謂的COMMIT_0UTC0ME來(lái)進(jìn)行配置。
[0157]在一個(gè)實(shí)施例中,如果在驗(yàn)證用戶時(shí)設(shè)備上設(shè)置了 commit_outcome屬性,那就針對(duì)用戶會(huì)話創(chuàng)建和管理LTXID。如果commit_outcome屬性在連接之后設(shè)置,那么針對(duì)該會(huì)話就不在COMMIT處跟蹤LTXID。如果commit_outcome被設(shè)定為FALSE,那么支持LTXID的現(xiàn)有會(huì)話就繼續(xù)支持LTXID。
[0158]在一個(gè)實(shí)施例中,如果創(chuàng)建會(huì)話請(qǐng)求沒(méi)有成功完成并且用戶重試該操作,那就生成新的邏輯事務(wù)標(biāo)識(shí)符。在本實(shí)施例中,舊的邏輯事務(wù)標(biāo)識(shí)符不再重新使用。
[0159]在一個(gè)實(shí)施例中,LTXID上含有數(shù)據(jù)庫(kù)的唯一名稱和實(shí)例編號(hào)。利用LTXID接收事務(wù)輸出請(qǐng)求的服務(wù)器可以識(shí)別原始數(shù)據(jù)庫(kù)和實(shí)例,其中的事務(wù)利用作為L(zhǎng)TXID —部分的數(shù)據(jù)庫(kù)和實(shí)例標(biāo)識(shí)符來(lái)提交。
[0160]圖8示出了用于保存數(shù)據(jù)庫(kù)系統(tǒng)內(nèi)的事務(wù)狀態(tài)的示例性方法的各個(gè)階段。新的會(huì)話在步驟812開始。在該實(shí)例中,只要事務(wù)不發(fā)生任何改變,服務(wù)器就以典型的方式運(yùn)行。當(dāng)應(yīng)用程序在步驟814發(fā)出創(chuàng)建首次redo的第一次改變之后,在步驟816注冊(cè)兩種交付回調(diào):交付前回調(diào)和交付后回調(diào)。在事務(wù)交付時(shí),交付前回調(diào)和交付后回調(diào)被自動(dòng)調(diào)用。在步驟818,在事務(wù)于步驟820交付至磁盤之前調(diào)用交付前回調(diào)。在步驟822,在事務(wù)交付至磁盤之后調(diào)用交付后回調(diào)。
[0161]在一個(gè)實(shí)施例中,服務(wù)器在事務(wù)已交付且執(zhí)行的COMMIT語(yǔ)句在PL/SQL或Java模塊內(nèi)嵌套或者是來(lái)自這些模塊和函數(shù)的返回語(yǔ)句時(shí)將事務(wù)性命令集的輸出設(shè)定為EMBEDDED (已嵌入),COMMIT語(yǔ)句在存儲(chǔ)Java的過(guò)程中嵌套,或者COMMIT語(yǔ)句通過(guò)返回附加信息的調(diào)用來(lái)執(zhí)行。返回處理行號(hào)的AUT0C0MMIT模式以及能夠在包括事務(wù)中的SELECT在內(nèi)的任何命令上設(shè)置的COMMIT ON SUCCESS就是應(yīng)用程序在COMMIT之后預(yù)計(jì)最終在哪里獲得更多信息的實(shí)例。服務(wù)器識(shí)別COMMIT是不是PL/SQL執(zhí)行堆棧內(nèi)的最后一項(xiàng),并且在執(zhí)行COMMIT時(shí)如果PL/SQL沒(méi)有可返回的函數(shù)結(jié)果或輸出參數(shù)就將用于LTXID的COMMIT輸出設(shè)定為COMMITTED (已交付)而不是EMBEDDED。在一個(gè)實(shí)例中,如果COMMIT是PL/SQL執(zhí)行堆棧內(nèi)唯一的COMMIT,那么服務(wù)器就將COMMIT輸出設(shè)定為COMMITTED而不是EMBEDDED。在另一個(gè)實(shí)例中,如果COMMIT先前在同一次PL/SQL執(zhí)行中被設(shè)定為EMBEDDED并且最后一次的COMMIT執(zhí)行和PL/SQL并未獲得可返回的函數(shù)結(jié)果或輸出參數(shù),那么服務(wù)器就將COMMIT輸出設(shè)定為COMMITTED。在另一個(gè)實(shí)例中,如果隱含的COMMIT是PL/SQL執(zhí)行堆棧內(nèi)的最后一項(xiàng),那么服務(wù)器就將COMMIT輸出設(shè)定為COMPLETED (已完成)而不是EMBEDDED。
[0162]在一個(gè)實(shí)例中,DDL命令作為依賴于DDL命令的遞歸和頂層的COMMIT組合而執(zhí)行。COMMIT執(zhí)行的編號(hào)和執(zhí)行的層級(jí)都是DDL專用的。在實(shí)例中,如果DDL命令中出現(xiàn)任何交付,那么DDL命令就遞加LTXID。用于LTXID的COMMIT輸出在運(yùn)行至完成時(shí)被更新為COMMITTED ο根據(jù)DDL命令執(zhí)行的中間COMMIT具有的中間COMMIT輸出為EMBEDDED。在一個(gè)特定的實(shí)例中,DDL命令將LTXID準(zhǔn)確地遞加一。換句話說(shuō),在該特定實(shí)例中,無(wú)論COMMIT的編號(hào)如何,具有遞歸COMMIT的命令集都超前LTXID恰好一步。在另一個(gè)實(shí)施例中,LTXID以某種其他的能夠跟客戶端共享的一致或可預(yù)測(cè)的方式改變。這就確保了 LTXID交付序列在到服務(wù)器的任何往返行程中都跟客戶端同步。
[0163]下表示出了命令結(jié)構(gòu)以及用于存留LTXID的對(duì)應(yīng)過(guò)程的幾個(gè)示例。
[0164]
【權(quán)利要求】
1.一種方法,包括: 在第二會(huì)話中由服務(wù)器從客戶端接收請(qǐng)求,所述請(qǐng)求利用第一會(huì)話的邏輯標(biāo)識(shí)符識(shí)別出由客戶端在第一會(huì)話中發(fā)送的一條或多條命令的集合;其中所識(shí)別的一條或多條命令的集合如果在第一會(huì)話中已完成將促使實(shí)施: 交付事務(wù)的第一服務(wù)器操作; 由服務(wù)器確定事務(wù)尚未交付;并且 響應(yīng)于所述請(qǐng)求并至少部分地基于確定事務(wù)尚未交付,服務(wù)器阻止第一會(huì)話中的事務(wù)完成。
2.如權(quán)利要求1所述的方法,進(jìn)一步包括由服務(wù)器促使完成第二會(huì)話中的一條或多條命令的集合;其中事務(wù)在第一會(huì)話和第二會(huì)話兩者中最多交付一次。
3.如權(quán)利要求1或2中的任意一項(xiàng)所述的方法,其中所述請(qǐng)求至少部分地基于在第一會(huì)話中完成先前的命令集之后被客戶端接收到的邏輯標(biāo)識(shí)符來(lái)識(shí)別所述一條或多條命令的集合。
4.如權(quán)利要求1至3中的任意一項(xiàng)所述的方法,其中所述服務(wù)器是托管第二會(huì)話的第二服務(wù)器,并且其中完成第一會(huì)話中的事務(wù)需要托管第一會(huì)話的第一服務(wù)器存留關(guān)于所識(shí)別的命令集的輸出的存儲(chǔ)信息。
5.如權(quán)利要求4所述的方法,其中阻止第一會(huì)話中的事務(wù)完成包括在第一會(huì)話以外存留關(guān)于所識(shí)別的命令集的輸出的存儲(chǔ)信息。
6.如權(quán)利要求5所述的方法,其中所述存儲(chǔ)信息在事務(wù)交付時(shí)被存留在事務(wù)歷史表內(nèi),并且其中事務(wù)歷史表可供對(duì)數(shù)據(jù)庫(kù)提供訪問(wèn)的包括所述服務(wù)器在內(nèi)的多個(gè)服務(wù)器訪問(wèn)。
7.如權(quán)利要求1至6中的任意一項(xiàng)所述的方法,其中所述一條或多條命令的集合是從客戶端到服務(wù)器的單用戶調(diào)用,并且其中所述單用戶調(diào)用如果在第一會(huì)話中完成將促使除了第一服務(wù)器操作以外的多項(xiàng)服務(wù)器操作的實(shí)施;其中所述多項(xiàng)服務(wù)器操作促使交付多項(xiàng)改變。
8.如權(quán)利要求1至7中的任意一項(xiàng)所述的方法,其中所述一條或多條命令的集合如果在所述會(huì)話中完成將在第一服務(wù)器操作和第二服務(wù)器操作之間促使至少一項(xiàng)服務(wù)器操作的實(shí)施以向客戶端發(fā)送所識(shí)別的一條或多條命令的集合已交付的指示;其中所識(shí)別的一條或多條命令的集合已交付的指示直到第一服務(wù)器操作已交付事務(wù)并完成所述一條或多條命令的集合之后才發(fā)往客戶端。
9.如權(quán)利要求8所述的方法,其中所述第一服務(wù)器操作如果在第一會(huì)話中完成就交付至少一項(xiàng)服務(wù)器操作對(duì)數(shù)據(jù)庫(kù)內(nèi)的一個(gè)或多個(gè)數(shù)據(jù)庫(kù)對(duì)象實(shí)施的一項(xiàng)或多項(xiàng)臨時(shí)改變。
10.如權(quán)利要求1至3或7至9中的任意一項(xiàng)所述的方法,其中所述服務(wù)器是在多個(gè)會(huì)話中對(duì)數(shù)據(jù)庫(kù)提供訪問(wèn)的多個(gè)服務(wù)器中的第二服務(wù)器;其中多個(gè)會(huì)話中的每個(gè)會(huì)話每次最多被分配給一個(gè)服務(wù)器;其中由客戶端在第二會(huì)話中發(fā)送一條或多條命令的集合之前,第一服務(wù)器在第一會(huì)話中向客戶端提供對(duì)數(shù)據(jù)庫(kù)的訪問(wèn);其中客戶端在第一會(huì)話中完成先前的命令集之后從第一服務(wù) 器接收邏輯標(biāo)識(shí)符;其中由客戶端在第一會(huì)話中發(fā)送一條或多條命令的集合之后第一會(huì)話變?yōu)閷?duì)客戶端不可用;并且其中所述請(qǐng)求至少部分地基于在第一會(huì)話中完成先前的命令集之后被客戶端接收到的邏輯標(biāo)識(shí)符來(lái)識(shí)別一條或多條命令的集合。
11.如權(quán)利要求1至2或4至10中的任意一項(xiàng)所述的方法,其中所述一條或多條命令的集合是一條或多條命令的第一集合,其中針對(duì)輸出的請(qǐng)求至少部分地基于在第一會(huì)話中發(fā)送的多個(gè)命令集中的一條或多條命令的第一集合所特有的邏輯標(biāo)識(shí)符來(lái)識(shí)別所述一條或多條命令的第一集合,其中標(biāo)識(shí)符至少部分地基于在第一會(huì)話中發(fā)送的一條或多條命令的先前集合完成后才發(fā)送至客戶端的指示,其中一條或多條命令的先前集合由客戶端在第一會(huì)話中先于一條或多條命令的第一集合發(fā)送。
12.如權(quán)利要求1至2或4至10中的任意一項(xiàng)所述的方法,其中針對(duì)輸出的請(qǐng)求至少部分地基于包括先前在第一會(huì)話中發(fā)送至客戶端的信息的邏輯標(biāo)識(shí)符來(lái)識(shí)別所述一條或多條命令的集合,其中所述邏輯標(biāo)識(shí)符唯一地識(shí)別出: 在所述會(huì)話中發(fā)送的一條或多條命令的多個(gè)集合中的所述一條或多條命令的集合;以及 在多個(gè)服務(wù)器對(duì)數(shù)據(jù)庫(kù)提供訪問(wèn)的多個(gè)會(huì)話中的所述會(huì)話,其中多個(gè)會(huì)話中的每個(gè)會(huì)話每次最多被分配給一個(gè)服務(wù)器。
13.如權(quán)利要求1至12中的任意一項(xiàng)所述的方法,進(jìn)一步包括: 向客戶端發(fā)送指示一條或多條命令的不同集合已交付的不同消息; 如果被交付就在送往客戶端的不同消息中附帶一條或多條命令的不同集合中的不同邏輯標(biāo)識(shí)符,其中所述不同消息包括一條或多條命令的不同集合中不同的結(jié)果集合。
14.一種或多種存儲(chǔ)指令的計(jì)算機(jī)可讀取介質(zhì),所述指令在由一個(gè)或多個(gè)處理器執(zhí)行時(shí)促使如權(quán)利要求1至13中的任意一項(xiàng)所述方法中的實(shí)施。
15.—種服務(wù)器,包括: 用于在第二會(huì)話中從客戶端接收請(qǐng)求的裝置,所述請(qǐng)求利用第一會(huì)話的邏輯標(biāo)識(shí)符識(shí)別出由客戶端在第一會(huì)話中發(fā)送的一條或多條命令的集合;其中所識(shí)別的一條或多條命令的集合如果在第一會(huì)話中已完成將促使實(shí)施: 交付事務(wù)的第一服務(wù)器操作; 用于確定事務(wù)尚未交付的裝置;以及 用于響應(yīng)于所述請(qǐng)求并至少部分地基于確定事務(wù)尚未交付而阻止第一會(huì)話中的事務(wù)完成的裝置。
【文檔編號(hào)】H04L29/08GK103782574SQ201280043616
【公開日】2014年5月7日 申請(qǐng)日期:2012年9月7日 優(yōu)先權(quán)日:2011年9月9日
【發(fā)明者】C·L·科爾瑞恩, S·H·羅艾斯科, K·S·尼爾 申請(qǐng)人:甲骨文國(guó)際公司