微軟的下一代數(shù)據(jù)庫系統(tǒng)(代號Yukon)已經(jīng)浮出水面。這一版本的數(shù)據(jù)庫系統(tǒng)有不少的新特色。比如它使用的Transact-SQL將更加符合ANSI-99 SQL的標(biāo)準(zhǔn),查詢語句將更靈活,更富表達(dá)性。Yukon允許程序員用.NET的語言,比如C#,VB.NET來開發(fā)自定義函數(shù)(user-defined functions),存儲過程(stored procedures)和觸發(fā)(triggers)。另外它還支持W3的XQuery語言,支持XML等等。
在Yukon的醞釀和設(shè)計過程中,設(shè)計師對下一代數(shù)據(jù)庫系統(tǒng)的編程能力下了很多氣力。微軟內(nèi)部的開發(fā)人員認(rèn)為,下一代的數(shù)據(jù)庫系統(tǒng)一定要包括更多的對稱編程模式,對各種數(shù)據(jù)類型的查詢應(yīng)該更靈活。所謂的對稱編程模式是指對于常見的數(shù)據(jù)庫操作,用戶應(yīng)該可以使用XML,.NET或是傳統(tǒng)的T-SQL程序.
在這種設(shè)計思想的指導(dǎo)下,Yukon在許多方面有了大的拓展。首先,.NET的公用語言執(zhí)行環(huán)境(CLR)被融合到了新的系統(tǒng)里;第二,融合進(jìn)來的.NET提供了很多強(qiáng)有力的數(shù)據(jù)庫對象;第三,XML在這版的數(shù)據(jù)庫里得到了更好和更深的支持;第四,數(shù)據(jù)庫的服務(wù)器端提供了對XML查詢(XQuery)以及XML規(guī)范定義語言XSD的支持;第五,傳統(tǒng)意義上的T-SQL也得到了進(jìn)一步的增強(qiáng)
新的編程模式和新增的語言一道使得數(shù)據(jù)庫應(yīng)用的開發(fā)有了更豐富的選擇。新的體系結(jié)構(gòu)使得我們更容易構(gòu)造可靠的,可擴(kuò)展的,穩(wěn)定的應(yīng)用,并且開發(fā)的效率也得到了極大的提高。Yukon中還引入了全新的服務(wù)代理(Service Broker),一種分布式的一部消息傳遞機(jī)制,現(xiàn)在讓我們先看看編程語言方面的增強(qiáng)。
Transact-SQL 語言的增強(qiáng)
Yukon對微軟的T-SQL有了很多的增強(qiáng)。用戶可以在Yukon的Online幫助中得到詳細(xì)的信息,限于便服,在此不一一列了。新增的特色表明了微軟對ANSI-99 SQL標(biāo)準(zhǔn)的進(jìn)一步支持,同時也反映了對廣大用戶反饋意見的相應(yīng)。新的增強(qiáng)主要是為了使查詢更富有表達(dá)性。有幾種新增的查詢可以很好的覆蓋用戶常用的一些查詢類型。比如說,遞歸查詢可以返回有層次機(jī)構(gòu)的結(jié)果集合(hierarchical resultset)或是a bill of materials。
Yukon提供了新的PIVOT和UNPIVOT操作。這些操作的輸入是表格類的表達(dá)式(table-valued expression),其輸出結(jié)果同樣是表格類型。PIVOT操作是將行轉(zhuǎn)變?yōu)榱?,并進(jìn)行集合以及其他的數(shù)學(xué)操作。在輸入的表格中它將以一個給定的列為軸進(jìn)行旋轉(zhuǎn),其成生的表格的列是有不同值的原旋轉(zhuǎn)列。這種操作使得生成的表格變寬(設(shè)想一個5列100行的輸入表格,其結(jié)果可能是100列5行的表格)。UNPIVOT是PIVOT的逆操作。它將輸入表格的列轉(zhuǎn)換為行。其結(jié)果是使輸入表格變窄。
Yukon的異常捕捉和處理機(jī)制也有了很大的變化。它使用了和.NET一致的TRY/CATCH結(jié)構(gòu)。導(dǎo)致交易終止的錯誤將會被捕捉并且處理。另外為了配合.NET的框架提供的安全,復(fù)制,提示服務(wù)以及XML等等功能(security, replication, Notification Services, XML),Yukon引入了不少新的語言構(gòu)造。.NET在服務(wù)器端的技術(shù)也極大了影響了SQL數(shù)據(jù)庫的研制和發(fā)展。
在SQL服務(wù)器中使用.NET來編程
程序員可以在Yukon中使用和.NET兼容的高級程序語言進(jìn)行開發(fā),利用VB.NET,C#這一類的語言編寫自定義函數(shù)(user-defined functions),存儲過程(stored procedures)和觸發(fā)(triggers)。另外,利用管理程序(managed code)還可以開發(fā)自定義函數(shù)(UDTs),集合(aggregates),函數(shù)(functions)。公用語言執(zhí)行環(huán)境(CLR)是.NET的核心,它是一切基于.NET開發(fā)的程序的運(yùn)行平臺。它提供了諸多的服務(wù),比如實(shí)時編譯(just-in-time compilation),內(nèi)存管理和分配(memory management and allocation),類型安全強(qiáng)制(type safety enforcement),異常處理(exception handling),線程管理(thread management)以及安全檢查(security)等等(CLR對于.NET程序就好比Java的虛擬機(jī)對于Java程序一樣)。在Yukon中,.NET程序?qū)⒑驮贑LR中完全相同的方式運(yùn)行。
將CLR整合到Y(jié)ukon中的好處是顯而易見的。Yukon獲得了CLR的各種有益的功能,如自動的內(nèi)存管理,資源分配,垃圾回收等等。Yukon提供了一套.NET assemblies,這樣允許程序員直接操作數(shù)據(jù)庫對象。數(shù)據(jù)的操作是通過一套特殊的ADO.NET來實(shí)現(xiàn)的。這些新的方法和原來的ADO.NET非常相似,程序員應(yīng)該感到非常的熟悉和親切。細(xì)一點(diǎn)說,我們可以把Yukno集成了CLR的好處歸結(jié)為以下幾點(diǎn):
1.豐富了編程模式。CLR兼容的高級程序語言比T-SQL要豐富的多,也強(qiáng)大的多。它們提供的功能和特色是以往SQL程序員不敢想象的。此外,Yukon還提供了一系列的類庫(Framework APIs),這些類庫的功能比以前SQL內(nèi)置的功能強(qiáng)大的多。
2.增強(qiáng)了安全性。管理程序運(yùn)行于數(shù)據(jù)苦支持的CLR環(huán)境當(dāng)中。這使得數(shù)據(jù)庫的對象比以往的擴(kuò)展存儲過程(extended stored procedures)更安全?! ?
3.用戶自定義的類型和集合。通過對CLR的集成,這兩個新增的對象擴(kuò)展了SQL數(shù)據(jù)庫的查詢和存儲能力?! ?
4.為今后的Visual Studioreg;開發(fā)環(huán)境指明了方向。今后程序員可以向開發(fā)其他.NET程序那樣用VB.NET或是C#這類的高級語言進(jìn)行數(shù)據(jù)庫的開發(fā),調(diào)試工作?! ?
5.性能的增強(qiáng)。在一些情況下,.NET語言的編譯和執(zhí)行可以提供比T-SQL更好的性能。
充分開發(fā)CLR的潛能
在以前的SQL數(shù)據(jù)庫應(yīng)用的開發(fā)中,服務(wù)器端的程序被限制于T-SQL。而在新的Yukon中,由于集成了CLR,使得開發(fā)工作變得前所未有的容易和方便。像VB.NET和C#這類的高級語言,全面支持?jǐn)?shù)組(Array),結(jié)構(gòu)化的異常處理(structured exception handling)以及各種集合操作(Collections)。這些功能使得程序員可以編寫更復(fù)雜的邏輯和計算工作。
更突出的一點(diǎn)就是Visual Basic .NET and C# 是面向?qū)ο蟮恼Z言,它們自身所具有的數(shù)據(jù)封裝(encapsulation),繼承(inheritance)和多態(tài)性(polymorphism)是T-SQL所不能比擬的。在大型系統(tǒng)的開發(fā)中,這種基于模塊化開發(fā)機(jī)制的優(yōu)越性會更加明顯。它可以更好的組織你的源程序,增加代碼的重用性。將源程序按照邏輯關(guān)系編譯成不同的assemblies和n字域(namespaces)可以增強(qiáng)程序的組織性,讓程序員更方便的瀏覽和使用已有的程序。
Yukon實(shí)現(xiàn)了三個層次的assemblies安全的管理控制。這種安全機(jī)制是對以往基于用戶驗(yàn)證和授權(quán)機(jī)制和新的CLR安全機(jī)制的有機(jī)合成。新的三級管理層次為:
最高層次: 安全接觸(SAFE)。它只允許接觸和計算數(shù)據(jù)
次高層次: 外部接觸(EXTERNAL_ACCESS)。它允許接觸外部的系統(tǒng)資源
最低層次: 不安全接觸(UNSAFE)。只要不對系統(tǒng)的穩(wěn)定性造成影響,就不加限制?! ?
在T-SQL和管理程序(Managed code)之間的取舍
管理程序非常適于進(jìn)行數(shù)字密集型的計算和復(fù)雜的邏輯處理。.NET對于字符串 (String),規(guī)則表達(dá)式(regular expressions),錯誤捕捉等等有著更好的支持。另外.NET提供的上千個類(Class) 和方法可以在自定義函數(shù)(user-defined functions),存儲過程(stored procedures)和觸發(fā)(triggers)中很方便的使用。所以對于有大量字符創(chuàng)操作,數(shù)學(xué)計算,日期運(yùn)算,系統(tǒng)資源存取,高級加密運(yùn)算,文件操作,圖像處理或是XML的情形,管理的存儲過程,函數(shù),觸發(fā),集合要比傳統(tǒng)意義上的T-SQL等強(qiáng)大和簡潔。
使用管理的程序的另外一個好處就是類型安全。在管理的程序執(zhí)行之前,CLR要對其進(jìn)行檢查以保證它的安全運(yùn)行。比如說,對于一個內(nèi)存讀寫的操作,CLR要先進(jìn)行檢查以保證在讀取的時候沒有寫操作在進(jìn)行。
在準(zhǔn)備編寫存儲過程,觸發(fā),或是UDFs之前,你要權(quán)衡各種情況,在傳統(tǒng)的T-SQL和管理程序(Managed code)之間做出選擇。選擇的標(biāo)準(zhǔn)是你當(dāng)前問題的具體特點(diǎn)。如果你的主要操作是數(shù)據(jù)存取以及相對簡單的邏輯運(yùn)算,那么T-SQL則非常合適。對于有大量數(shù)值計算以及復(fù)雜邏輯運(yùn)算的情況,管理程序(Managed code)則更適用。
程序放置在什么地方也是很關(guān)鍵的一步。T-SQL和管理程序(Managed code)都是在數(shù)據(jù)庫的引擎內(nèi)運(yùn)行。把.NET和數(shù)據(jù)庫緊密放置在一起可以有效的發(fā)揮服務(wù)器的硬件運(yùn)算能力。當(dāng)然最好是用SQL數(shù)據(jù)庫的Profile程序來測量一下你的具體程序的運(yùn)行性能,然后再做出決定。Yukon的Profile程序有了進(jìn)一步的增強(qiáng)??梢愿顚哟蔚臏y量SQL數(shù)據(jù)庫內(nèi)的CLR的性能,并且會以更直觀的圖形方式來輸出對比測試結(jié)果。下面就讓我們來具體看看Yukon中新增的一些功能。
用戶定義的類,函數(shù)和集合(User-defined Types, Functions, and Aggregates)
Yukno支持?jǐn)U展的CLR的類系統(tǒng)。這些擴(kuò)展的類可以在服務(wù)器端定義表(table),也可以在客戶端進(jìn)行數(shù)據(jù)操作。用戶自定義類型(UTDs)允許用戶擴(kuò)展已有的類。這些擴(kuò)展的具體實(shí)現(xiàn)是用的管理程序(managed code)。比如說,你可以定義一些用于地理空間的類型,一些特殊的金融類型或是特別的時間日期類型以適應(yīng)你獨(dú)特的要求。
用.NET的術(shù)語來說,UTDs是結(jié)構(gòu)(struct)或是參考類型(reference type),而不是類(class)或枚舉(enum)。這意味著內(nèi)存的是用是由CLR控制優(yōu)化的。不過,UTDs不支持繼承和多態(tài)性(inheritance and polymorphism)。它可以有公用或是私有函數(shù)(public and private functions)。事實(shí)上,諸如限制檢查(constraint checking)應(yīng)該由私有函數(shù)來完成。舉例來說吧,如果你想定義一個地理空間的類型,這可能包含經(jīng)度,緯度也許還有高度信息,你可以定義相應(yīng)的私有成員來完成這一任務(wù)。這類型創(chuàng)建完成后,你可以把他注冊到SQL數(shù)據(jù)庫中。這個被編譯的DLL就會被存放在SQL數(shù)據(jù)庫中。
用戶自定義函數(shù)(UDFs)有兩種類型:一種是標(biāo)量值型的(scalar-valued),這種函數(shù)返回單一的值,如字符串,整數(shù),比特等等。另外一種是表格值型的(Table-valued)。這種函數(shù)返回有一個或多個列組成的數(shù)據(jù)集合。
Yukon允許用戶定義新的集合(aggregate)操作的能力遠(yuǎn)遠(yuǎn)超過了以前的版本。用戶用管理語言開發(fā)的集合可以被T-SQL或是其他的管理語言調(diào)用。這些新開發(fā)的集合是.NET的類,它可以引用數(shù)據(jù)庫中存在的其他編譯好的類庫(Class Library)。你可以使用用戶定義的集合將數(shù)據(jù)庫中的數(shù)據(jù)轉(zhuǎn)化為數(shù)值型變量。比如你最近的一次用戶調(diào)查的數(shù)據(jù)存放到數(shù)據(jù)庫中,通過一個用戶定義的統(tǒng)計函數(shù)你可以得到加權(quán)平均或是標(biāo)準(zhǔn)偏差。
管理的存儲過程
這是一種管理程序,其工作方式就像傳統(tǒng)的存儲過程一樣。如果你希望返回一個簡單的數(shù)據(jù)集和(resultset)或是只是進(jìn)行一個數(shù)據(jù)操作(使用DML或是DDL)。一旦被注冊到數(shù)據(jù)庫中,那么使用它就像是用一個普通的存儲過程那樣。將一段管理程序包裝成存儲過程的語法如下(基于現(xiàn)在早期的Yukon版本)
CREATE PROCEDURE mysproc (@username NVARCHAR(4000))
AS
EXTERNAL NAME YukonCLR:[MyNamespace.CLRCode]:: myfunction
(未完)
XML和Yukon數(shù)據(jù)庫
對XML的支持開始于SQL 2000。這個版本的SQL可以將關(guān)系數(shù)據(jù)以XML形式返回;從XML批量載入數(shù)據(jù);分享XML文檔;將數(shù)據(jù)庫對象發(fā)布成為基于XML的Web services。Web services的開發(fā)工具SQLXML 3.0對存儲過程,XML,以及SQL的UDFs提供了Web services的支持。SQL 2000對于XML支持的不足之處在于缺乏內(nèi)部的XML存儲機(jī)制以及復(fù)雜的查詢半結(jié)構(gòu)化數(shù)據(jù)的能力。Yukon在這兩個關(guān)鍵問題上有了長足的進(jìn)步。
XML數(shù)據(jù)類型
XML是從一種表達(dá)型的技術(shù)演化而來,到現(xiàn)在XML以被視為一種存儲信息的方式。如何保存XML變成了一個非常有趣的話題。XML文檔可以在應(yīng)用程序中有很多不同的使用。
1.當(dāng)你不知道XML規(guī)范(schemas )的時候;
2.當(dāng)XML規(guī)范是動態(tài)變化的時候(dynamic schemas);
3.XML的保存是應(yīng)用程序的中心。
很難用一個例子來說明XML的應(yīng)用方法和方式。在下文中給出的例子中,XML被作為一種存儲形式,使用動態(tài)規(guī)范(dynamic schema)來表達(dá)客戶從網(wǎng)上訂戶的信息。
XML數(shù)據(jù)類型是一個很完備的(full-fledged)。它有其他SQL數(shù)據(jù)類型的一切能力。同時,作為一個完備的數(shù)據(jù)類型,XML是可以被索引的。它可以通過XSD schema對行和列的值加以限制(constraints)。它還可以被T-SQL中嵌入的XQuery查詢。此外,使用xmldt::modify方法,用戶可以增加,刪除子樹和更新標(biāo)量值(update scalar values)
XML數(shù)據(jù)是非常靈活的。你可以選擇是否要對這個XML列關(guān)聯(lián)一個規(guī)范定義(XML Schema Definition,XSD)。如果你選擇了XSD,那么這個列成為有類型的XML(typed XML)。如果沒有相應(yīng)的XSD,那么這個XML稱為沒有類型的XML(untyped XML)。輸入XSD到一個表格的XML列,可以類型這個列。XSD可以被用來生成索引以及其他一些系統(tǒng)目錄(system catalog)所需要的要信息。有類型的XML比沒有類型的XML可以更快和更有效的操作。
要注意的是你可以在一個列中存儲整個XML文檔或是其中的一部分。另外,你還可以對這個列生成特殊的XML索引。這樣就對XML中的標(biāo)簽(tag), 值(value)何路徑(path)生成了索引。
XSD and XML數(shù)據(jù)類型
當(dāng)創(chuàng)建你的XML列時,以可以加入XSD文檔并將之和你的列聯(lián)系起來。XSD schema的聯(lián)系在SQL的Workbench中完成。(使用DDL也可以完成這一聯(lián)系)
當(dāng)一個schema輸入到數(shù)據(jù)庫中的時候,它會被分解為不同的組件(component),包括元素(ELEMENT),屬性(ATTRIBUTE),類別(TYPE),屬性群(ATTRIBUTEGROUP)等等。這些部分以及相關(guān)聯(lián)的字域(namespaces)被存到系統(tǒng)的不同表格當(dāng)中去。你可以用系統(tǒng)專用的視圖來看這些組件。也就是說,schema不是原封不動被存儲的。至少有兩個分支產(chǎn)生。一是schema的標(biāo)簽(Tag)和屬性沒有被保存,二是一旦schema被輸入到數(shù)據(jù)庫中,它不能保證可以還恢復(fù)到原先的樣子。所以你最好保存一份原先的schema,或是將其存放到一個專用的表格中去(對于這個任務(wù),XML列就是非常勝任的)。另外一個辦法是使用內(nèi)置的函數(shù)XML_SCHEMA_NAMESPACE來得到XML schemas。
當(dāng)XML列和XSD schema組合的時候,XML數(shù)據(jù)的查詢能力就是對普通關(guān)系數(shù)據(jù)的一個補(bǔ)充。將所有的數(shù)據(jù)保存為XML形式是不必要的,但是利用數(shù)據(jù)庫的XML能力確實(shí)方便了XML文檔的管理以及其他一些應(yīng)用。
XQuery
XML查詢通常被稱為XQuery。它是一種智能的可靠的語言,專門用于查詢各種XML數(shù)據(jù)。使用XQuery, 你可以用相應(yīng)的方法查詢XML數(shù)據(jù)的變量和列。使用最新的創(chuàng)新性的查詢方法,你可以對關(guān)系型數(shù)據(jù)以及XML數(shù)據(jù)進(jìn)行統(tǒng)一查詢。
我們知道XML有許多的標(biāo)準(zhǔn)。在Yukon的XQuery研發(fā)過程中盡量的遵循W3C的標(biāo)準(zhǔn)。XQuery的起源是個叫做Quilt的查詢語言。它是一種基于多種技術(shù)之上的查詢語言,比如XPath 1.0, XQL, and SQL。它同時還包括了XQuery 2.0的一部分。你可以繼續(xù)使用你的XPath的知識,不過Yukon有了許多的增強(qiáng),你也許想要學(xué)習(xí)這些新的東西。比如一些支持循環(huán),排序等操作的新函數(shù)?! ?
XQuery申明語句(Statement)包括一個導(dǎo)引和主體(a prologue and a body)。導(dǎo)引中包括一個或多個字域申明以及其他產(chǎn)生查詢內(nèi)容的規(guī)范(schema)的引用。主體包括一系列的表達(dá)式用來說明查詢的條件。這些申明語句可以在query, value, exist, or modify這樣幾種方法中對使用。
XQuery可以查詢有類型的XML(typed XML),及有相應(yīng)的規(guī)范(schema)的XML,它還可以查詢一般的XML文檔
微軟的XQuery設(shè)計程序 -- XQuery Designer
XQuery Designer是一個繼承在SQL Server Workbench得一個應(yīng)用程序,用以簡化XML工作的難度。它可以幫助你寫出對XML列以及XML文檔查詢的語句。其核心目的是使程序員不用大量學(xué)習(xí)XML的許多知識而容易的駕馭XQuery。
到這里,大家對Yukon中的.NET以及XML的能力有了一個大概的了解。組合使用這些技術(shù)可以很方便的解決以前認(rèn)為是相當(dāng)復(fù)雜的難題。Yukon的開發(fā)重點(diǎn)是分布式應(yīng)用。商業(yè)應(yīng)用的流程和邏輯將直接反映在數(shù)據(jù)庫程序當(dāng)中。Yukon還對基于Web的應(yīng)用有非常好的支持。
Yukon的服務(wù)代理(Service Broker)
SQL數(shù)據(jù)庫的服務(wù)代理可以讓內(nèi)部和外部的進(jìn)程通過擴(kuò)充的或是普通的T-SQL DML發(fā)送和接收有保證的,異步的消息。消息可以被傳遞到和發(fā)送者共享一個數(shù)據(jù)庫的隊列中去,或是同一個SQL進(jìn)程的其他數(shù)據(jù)庫中去,甚至是本機(jī)或是異機(jī)其他數(shù)據(jù)庫進(jìn)程的數(shù)據(jù)庫中去。
在以往的消息系統(tǒng)中,應(yīng)用程序要負(fù)責(zé)消息的收發(fā)和協(xié)調(diào)工作。消息的復(fù)制,同步以及次序的維護(hù)都是比較棘手的問題。
SQL數(shù)據(jù)庫的服務(wù)代理通過自動維護(hù)消息次序,唯一的發(fā)送和會話標(biāo)志很好地解決了這一難題。一旦兩個服務(wù)間的對話建立起來,兩端的程序被保證一個消息只接收一次,并且接收順序和發(fā)送順序一致。這樣你的程序不需要額外的語句就可以保證一個消息只被處理一次。SQL數(shù)據(jù)庫的服務(wù)代理自動為每一個消息加上一個唯一的標(biāo)志。一個應(yīng)用程序總可以知道某個消息是屬于哪一個會話。
服務(wù)代理將要發(fā)送的消息放到隊列中去。如果接收方一時沒有準(zhǔn)備好,那么消息會被保存在這個隊列中。服務(wù)代理不停的試發(fā)消息,直到消息被接收方受到為止。這樣可以保證會話的可靠性。即使接收方在一段時間內(nèi)沒有響應(yīng),消息也不會遺失。這種發(fā)送和接收方松散連接的模式使得雙方都有很大的靈活性。發(fā)送者只要將消息放到隊列中就可以返回去繼續(xù)他的工作。消息會由服務(wù)代理保證發(fā)送到接收方手里。一個消息可以發(fā)到多個接收者手里。這些接收者可以獨(dú)立的并行處理消息。其快慢可以根據(jù)當(dāng)時服務(wù)器負(fù)荷程度而定。
隊列還可以使得處理工作更均勻的分配,從而減少服務(wù)器負(fù)荷的大起大落。這樣從總體上提高了應(yīng)用的性能和吞吐量。比如說,訂貨的高峰總出現(xiàn)在每天中午。這種高峰增大了系統(tǒng)資源消耗,延長了處理時間。如果使用了服務(wù)代理,那么在接收訂貨的時候并不需要馬上完成所有的處理工作。許多工作可以在后臺慢慢處理。只要先保證客戶的訂單可以順暢的收到就可以了。
消息處理程序的一個難點(diǎn)就是如何實(shí)現(xiàn)讓多個程序從同一個隊列中并行讀取消息。因?yàn)椴僮鞑划?dāng)就會造成消息處理次序混亂,盡管收到的順序是正確的。
試想這樣一個典型的應(yīng)用。含有如何生成訂貨頭部信息的A消息和含有如何生成訂貨明細(xì)條目的B消息被放置在一個隊列中。如果他們被不同程序從隊列中取走進(jìn)行處理。很可能B消息的處理程序進(jìn)行得快而首先試圖確認(rèn)(commit)。但是由于頭部信息還沒有準(zhǔn)備好,所了確認(rèn)一定會失敗。這樣B消息就會被重新放置到隊列中等待再一次處理。這顯然是一種浪費(fèi)。以往對于這種問題的解決辦法就是將A消息B消息合并為一個消息。對于簡單的兩個消息這種辦法還可以,但如果對于有上百個消息的復(fù)雜情況,這種辦法顯然就不適用了。
服務(wù)代理通過鎖定屬于一個任務(wù)(Task)的所有消息來解決這個難題。這樣這些消息只能被一個處理程序接收和處理。而同時其他處理程序可以接收和處理屬于其它任務(wù)的消息。這種機(jī)制保證多個處理程序可以可靠和有效的并行工作。
服務(wù)代理的一個最有用的功能就是“激活”(activation)了。激活可以在收到消息的時候自動啟動消息處理程序。如果消息來的速度大于處理的速度,那么多個消息處理程序就會被啟動,直到達(dá)到了配置允許的最大值。如果消息來的速度減慢或是已經(jīng)沒有消息等待被處理了,那么消息處理程序?qū)魂P(guān)掉。這樣消息處理程序的數(shù)量將根據(jù)消息的數(shù)量和收到的速度自動動態(tài)的調(diào)節(jié)。如果系統(tǒng)崩潰或是重啟動,在系統(tǒng)恢復(fù)過來以后,消息處理程序會自動啟動來處理積壓的消息。以前的消息處理系統(tǒng)做不到這一點(diǎn),所以消息處理程序不是太多就是太少。
服務(wù)代理和數(shù)據(jù)庫的集成
集成的服務(wù)代理提供了性能上的以及管理上的好處。和SQL數(shù)據(jù)庫的集成使得交易式的消息傳遞成為可能。也就是說消息接收,處理和返回這樣一個循環(huán)變成了一個數(shù)據(jù)庫的交易,如果中間有一個環(huán)節(jié)出現(xiàn)錯誤,所有的工作將會被放棄,接收到的消息重新進(jìn)入處理隊列以被再一次處理。直到交易最終完成以前,沒有任何動作會產(chǎn)生效應(yīng)。這樣應(yīng)用程序?qū)⑹冀K保持一個一貫的狀態(tài),并且不會引入分布式交易處理的復(fù)雜性和過多的資源消耗。
當(dāng)數(shù)據(jù),消息和程序的邏輯全部存在與數(shù)據(jù)庫中的時候,管理工作也變得相對容易。象災(zāi)難恢復(fù),簇建立(clustering),安全控制,備份這些管理工作只需要面對一種東西而不是3種或4種分散的組件。比如說,在以前的消息系統(tǒng)中,消息存儲和數(shù)據(jù)庫可能會出現(xiàn)不一致。如果其中一個從備份上恢復(fù)過來,那么另外一個也必須從同一時間的備份上恢復(fù)過來,否則數(shù)據(jù)就會變得不統(tǒng)一。當(dāng)數(shù)據(jù)和消息被數(shù)據(jù)庫統(tǒng)一處理后,這個問題就變得不再是問題了。
使用統(tǒng)一的開發(fā)環(huán)境也帶來不少好處。應(yīng)用程序的消息處理部分和數(shù)據(jù)存取部分可以用統(tǒng)一的語言來完成。對于已經(jīng)熟悉數(shù)據(jù)庫開發(fā)的程序員,這可以極大的降低消息處理部分開發(fā)的難度。實(shí)現(xiàn)服務(wù)代理的存儲過程的可以用傳統(tǒng)的T-SQL或是.NET兼容的高級語言來開發(fā)。
另外,數(shù)據(jù)庫的集成使得資源的自動管理成為可能。服務(wù)代理運(yùn)行于SQL數(shù)據(jù)庫的空間之中,這樣代理就可以對該數(shù)據(jù)庫進(jìn)程中所有的已經(jīng)傳遞的消息有一個集成的全局的視角。這樣各個數(shù)據(jù)庫可以維持自己的消息隊列,而在全局上又盡可能保證資源分布的相對合理。
Yukon數(shù)據(jù)庫應(yīng)用開發(fā)的一個具體實(shí)例
我們假設(shè)有這樣一個應(yīng)用:用戶在網(wǎng)上訂購你公司的產(chǎn)品。這個在各個服務(wù)之間傳遞的消息存放在XML列中。為簡易起見,我們把這個應(yīng)用程序想象為SQL數(shù)據(jù)庫中CLR運(yùn)行的一個基于ASP.NET的Web service。這個服務(wù)和其他的伙伴傳遞客戶訂貨的消息。使用XML列來存儲消息可以封裝和簡化XML的Schema.
當(dāng)客戶的訂貨確定后,包含這個訂貨信息的消息被放置到訂貨隊列中去并放置在XML列中。這樣這個訂貨的所有信息就被存放到一個列中。
訂貨隊列是交易得開始。他接到消息并處理它。它向信用校核服務(wù)發(fā)送一個請求。如果客戶的信用沒有問題,那么它就進(jìn)行下一步的操作。
下一步是檢查現(xiàn)有的庫存。一個XQuery來查詢庫存情況。如果有庫存,那么操作走向下一步,發(fā)貨。
在發(fā)貨步驟中,一個T-SQL的存儲過程使用XQuery來解讀這個XML消息,客戶的信息被提取出來以生成發(fā)貨單。當(dāng)發(fā)貨完成后,這個消息就被轉(zhuǎn)到收款服務(wù)處。
但收款服務(wù)受到這個消息后,它更新客戶訂貨的狀態(tài),指明貨物已經(jīng)被發(fā)送。
另外,所有進(jìn)出訂貨服務(wù)的消息都被寫到一個審計表格中以備將來可能的審核以及錯誤更正。
從這個小例子中你可以看出,Yukon是如何集成使用XML,CLR,服務(wù)代理,增強(qiáng)的T-SQL來構(gòu)建一個可靠的,可擴(kuò)充的完備的數(shù)據(jù)庫應(yīng)用。
結(jié)論:
以上介紹的只是Yukon中一些令人振奮的新特色和功能。數(shù)據(jù)庫開發(fā)人員如今有了更多的選擇。上一個小例子示范了一部分Yukon中新增的能力。更多的特色和功能還有待于我們進(jìn)一步挖掘!