數據庫事務&存儲過程

一、【事務概念】

事務(Transaction)是指構成單一邏輯工作單元的操作集合,要麼完整地執行,要麼完全不執行。

1,如果事務中有的操作沒有成功完成,則事務中的所有操作都需要被回滾,回到事務執行前的狀態(要麼全執行,要麼全都不執行);

2,同時,該事務對數據庫或者其他事務的執行無影響,所有的事務都好像在獨立的運行。

二、【事務舉例】

用一個常用的“A 賬戶向 B 賬戶匯錢”的例子來說明如何通過數據庫事務保證數據的準確性和完整性。熟悉關係型數據庫事務的都知道從賬戶 A 到賬戶 B 需要 6 個操作,分別爲:

1.從 A 賬戶中把餘額讀出來(500)

2. 對 A 賬戶做減法操作(500 - 100)

3. 把結果寫回 A 賬戶中(400)

4. 從 B 賬戶中把餘額讀出來(500)

5. 對 B 賬戶做加法操作(500 + 100)

6. 把結果寫回 B 賬戶中(600)

三、【事務特性】

並非任意的對數據庫的操作序列都是數據庫事務,事務應該具有 4 個屬性,分別爲:原子性、一致性、隔離性和持久性。這四個屬性通常稱爲ACID特性。

1.原子性(Atomicity):一個事務對數據庫的所有操作,是一個不可分割的工作單元,這些操作要麼全部被執行,要麼都不執行;

保證 1-6 所有過程要麼都執行,要麼都不執行。

一旦在執行某一步驟的過程中發生問題,就需要執行回滾操作。

假如執行到第 5 步的時候,B 賬戶突然不可用(比如被註銷),那麼之前的所有操作都應該回滾到執行事務之前的狀態。

2.一致性(Consistency):事務應確保數據庫的狀態從一個一致狀態轉爲另一個一致狀態,一致狀態的含義是數據庫中的數據應滿足完整性約束;

在轉賬之前,A 和 B 的賬戶中共有 500 + 500 = 1000 元錢。

在轉賬之後,A 和 B 的賬戶中也應該共有 400 + 600 = 1000 元錢。

也就是說,數據的狀態在執行該事務操作之後從一個狀態改變到了另外一個狀態。同時一致性還能保證賬戶餘額不會變成負數等。

注:一致性與原子性是密切相關的,原子性的破壞可能導致數據庫的不一致,數據的一致性問題並不都和原子性有關。

比如上面的例子,在第5 步的時候,對 B 賬戶做加法時只加了 50 元。那麼,該過程可以符合原子性,但是數據的一致性就出現了問題。因此,事務的原子性與一致性缺一不可。

3.隔離性(Isolation):多個事務併發執行時,一個事務的執行不應影響其他事務的執行;

在 A 向 B 轉賬的整個過程中,只要事務還沒有提交(commit),查詢 A 賬戶和 B 賬戶的時候,兩個賬戶裏面的錢的數量都不會有變化。

如果在 A 給 B 轉賬的同時,有另外一個事務執行了 C 給 B 轉賬的操作,那麼當兩個事務都結束的時候,B 賬戶裏面的錢應該是 A 轉給 B 的錢加上 C 轉給 B 的錢再加上自己原有的錢。

4.持久性(Durability):一個事務一旦提交,它對數據庫的修改應該永久保存在數據庫中。

例如我們在數據庫,用update語句更新某條記錄時,會默認開啓一個數據庫事務,當我們執行(F8)這條語句後,再次查詢這條記錄,已經被更新,但沒有提交事務,事務並沒有對數據庫產生影響。此時如果關閉查詢窗口(出現故障),並未對數據庫記錄產生影響,只有將事務提交之後,這條記錄纔會真正並永久的更新。

四、【事務併發】

事務併發:一個數據庫可能擁有多個訪問客戶端,這些客戶端都可以併發方式訪問數據庫,數據庫中的相同數據可能同時被多個事務訪問,如果沒有采取必要的隔離措施,就會導致各種併發問題,破壞數據的完整性。

併發問題歸結:數據問題(髒讀、幻讀、不可重複讀)、數據更新問題(更新丟失)

 

 

一、【存儲過程的概念】

① 存儲過程(Stored Procedure)是一組爲了完成特定功能的SQL語句集。經編譯後存儲在數據庫中。

② 存儲過程是數據庫中的一個重要對象,用戶通過指定存儲過程的名字並給出參數(可以有參數,也可以沒有)來執行它。

③ 存儲過程是由 流控制 和 SQL語句書寫的過程,這個過程經編譯和優化後存儲在數據庫服務器中。

④ 存儲過程 可由應用程序通過一個調用來執行,而且允許用戶聲明變量。

⑤ 同時,存儲過程可以接收和輸出參數、返回執行存儲過程的狀態值,也可以嵌套調用。

二、【存儲過程的優點】

① 存儲過程的使用大大增強了SQL語言的功能和靈活性。

存儲過程可以用流控制語句編寫,有很強的靈活性,可以完成複雜的判斷和較複雜的運算。

② 可保證數據的安全性和完整性。

通過存儲過程可以使沒有權限的用戶在控制之下間接地存取數據庫,從而保證數據的安全。

通過存儲過程可以使相關的動作在一起發生,從而可以維護數據庫的完整性。(就像事務的原子性:要麼事務內的所有SQL語句全部執行成功,要麼全部不成功)

③ 在運行存儲過程前,數據庫已對其進行了語法和句法分析,並給出了優化執行方案。

這種已經編譯好的過程可極大地改善SQL語句的性能。

由於執行SQL語句的大部分工作已經完成(因爲已經提前經過編譯),所以存儲過程能以極快的速度執行。

④ 可以降低網絡的通信量。

客戶端調用存儲過程只需要傳存儲過程名和相關參數即可,與傳輸SQL語句相比自然數據量少了很多(在遠程訪問時體現出來)。

⑤ 存儲過程只在創造時進行編譯,以後每次執行存儲過程都不需再重新編譯,而一般SQL語句每執行一次就編譯一次,所以使用存儲過程可提高數據庫執行速度。

⑥ 當對數據庫進行復雜操作時(如對多個表進行Update,Insert,Query,Delete時),可將此複雜操作用存儲過程封裝起來與數據庫提供的事務處理結合一起使用。

比如每一步對數據庫的操作用一個事務來完成,把這些事務全都放在一個存儲過程中。

⑦ 存儲過程可以重複使用,可減少數據庫開發人員的工作量。

⑧ 安全性高,可設定只有某些用戶才具有對指定存儲過程的使用權

三、【存儲過程缺點】

① 調試麻煩:但是用 PL/SQL Developer 調試很方便!彌補這個缺點。

② 移植問題:數據庫端代碼當然是與數據庫相關的。但是如果是做工程型項目,基本不存在移植問題。

③ 重新編譯問題:因爲後端代碼是運行前編譯的,如果帶有引用關係的對象發生改變時,受影響的存儲過程、包將需要重新編譯(不過也可以設置成運行時刻自動編譯)。

比如A存儲過程調用B存儲過程,使用B的返回值作爲參數,如果B的參數或返回值發生改變時,會對調用她的A產生影響,此時存儲過程就要重新編譯,設置成運行時刻自動編譯。

④ 維護比較困難:如果在一個程序系統中大量的使用存儲過程,到程序交付使用的時候隨着用戶需求的增加會導致數據結構的變化,接着就是系統的相關問題了,最後如果用戶想維護該系統可以說是很難很難、而且代價是空前的,維護起來更麻煩。

四、【存儲過程的種類】

① 系統存儲過程:一般以sp_開頭,用來進行系統的各項設定,獲取配置信息,相關管理工作。

② 本地存儲過程:用戶創建的存儲過程是由用戶創建並完成某一特定功能的存儲過程,事實上一般所說的存儲過程就是指本地存儲過程。

③ 臨時存儲過程:分爲兩種存儲過程:

一是本地臨時存儲過程,以井字號(#)作爲其名稱的第一個字符,則該存儲過程將成爲一個存放在tempdb數據庫中的本地臨時存儲過程,且只有創建它的用戶才能執行它;

二是全局臨時存儲過程,以兩個井字號(##)號開始,則該存儲過程將成爲一個存儲在tempdb數據庫中的全局臨時存儲過程,全局臨時存儲過程一旦創建,以後連接到服務器的任意用戶都可以執行它,而且不需要特定的權限。

④ 遠程存儲過程:在SQL Server2005中,遠程存儲過程(Remote Stored Procedures)是位於遠程服務器上的存儲過程,通常可以使用分佈式查詢和EXECUTE命令(在SQL*Plus命令行窗口中)執行一個遠程存儲過程。

⑤ 擴展存儲過程:擴展存儲過程(Extended Stored Procedures)是用戶可以使用外部程序語言編寫的存儲過程,而且擴展存儲過程的名稱通常以xp_開頭。

五、【存儲過程的特性】

1.存儲過程與函數的區別

①返回值:函數只能返回一個變量,而存儲過程可以返回多個。對於存儲過程來說可以返回參數,如記錄集,而函數只能返回值或者表對象

 ②存儲過程一般是作爲一個獨立的部分來執行( EXECUTE 語句執行),而函數可以作爲查詢語句的一個部分來調用(SELECT調用),由於函數可以返回一個表對象,因此它可以在查詢語句中位於FROM關鍵字的後面。 SQL語句中不可用存儲過程,而可以使用函數。 

③存儲過程實現的功能要複雜一點,而函數的實現的功能針對性比較強,比較單一。

2.存儲過程與事務的區別

①存儲位置:事務在程序中被調用,保存在調用以及實現它的代碼中,存儲過程可以在數據庫客戶端直接被調用,經編譯後存儲在數據庫中。

②運行方式:事務在每次被調用的時候執行其中的SQL語句,存儲過程預先經過編譯,並不是每次被調用時都會執行一遍其中的SQL語句。

③事務有嚴格的一致性和原子性,使用的安全性高,存儲過程則沒有這些特性,在進行一些複雜的操作時,爲了保證操作的準確性,可以在存儲過程中調用事務,然後判斷事務的執行結果是否成功來確保操作的準確性。

3.觸發器

①概念及作用

觸發器是一種特殊類型的存儲過程,它不同於我們前面介紹過的存儲過程。觸發器主要是通過事件進行觸發而被執行的,而存儲過程可以通過存儲過程名字而被直接調用。當對某一表進行諸如Update、 Insert、 Delete 這些操作時,SQL Server就會自動執行觸發器所定義的SQL 語句,從而確保對數據的處理必須符合由這些SQL 語句所定義的規則。

觸發器的主要作用就是其能夠實現由主鍵和外鍵所不能保證的複雜的參照完整性和數據的一致性。除此之外,觸發器還有其它許多不同的功能:

(1) 強化約束(Enforce restriction)

觸發器能夠實現比CHECK 語句更爲複雜的約束。

(2) 跟蹤變化(Auditing changes)

觸發器可以偵測數據庫內的操作,從而不允許數據庫中未經許可的指定更新和變化。

(3) 級聯運行(Cascaded operation)。

觸發器可以偵測數據庫內的操作,並自動地級聯影響整個數據庫的各項內容。例如,某個表上的觸發器中包含有對另外一個表的數據操作(如刪除,更新,插入)而該操作又導致該表上觸發器被觸發。

(4) 存儲過程的調用(Stored procedure invocation)。

爲了響應數據庫更新,觸發器可以調用一個或多個存儲過程,甚至可以通過外部過程的調用而在DBMS(數據庫管理系統)本身之外進行操作。

由此可見,觸發器可以解決高級形式的業務規則或複雜行爲限制以及實現定製記錄等一些方面的問題。例如,觸發器能夠找出某一表在數據修改前後狀態發生的差異,並根據這種差異執行一定的處理。此外一個表的同一類(Insert、 Update、Delete)的多個觸發器能夠對同一種數據操作採取多種不同的處理。

總體而言,觸發器性能通常比較低。當運行觸發器時,系統處理的大部分時間花費在參照其它表的這一處理上,因爲這些表既不在內存中也不在數據庫設備上,而刪除表和插入表總是位於內存中。可見觸發器所參照的其它表的位置決定了操作要花費的時間長短。

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章