VB.net 2010 視頻教程 VB.net 2010 視頻教程 VB.net 2010 視頻教程
SQL Server 2008 視頻教程 c#入門經典教程 Visual Basic從門到精通視頻教程
當前位置:
魔兽世界wow > 數據庫 > sql語句 >
  • sql語句大全之數據庫設計與事務處理

  • 2019-04-29 21:53 來源:未知

魔兽世界wow www.geyjm.icu 事務(transaction)其實就是一序列數據庫命令,他們可以組合在一起當做一個單一邏輯單元

在一個事務被標記為完成之前(commited),任何改變可以被回滾(rolled back)

例子:轉賬,它可以包括(減少發送錢賬戶的金額量,增加收款人的金額量,給發送方和接收方都增加交易記錄)

如果連接被打斷,或者說一些操作失敗了,所有的操作都需要被回滾

→ Total failure is better than partial failure

 

每一個事務的終止信號都是通過commit或者roll back來傳達的,沒有commit,我們做出的改變不會被保存

但其實Sesssions都是有自動提交功能(auto-commit)的,也就是任何命令都能被馬上提交,不需要roll back和commit,這種auto-commit方式都是被默認的(set sutocommit = 0 關閉autocommit)

→ START TRANSACTION or BEGIN

BEGIN;

UPDATE accounts SET balance = balance - 100.00 WHERE acc_nr = 254231426;

UPDATE accounts SET balance = balance + 100.00 WHERE acc_nr = 676535301;

INSERT INTO transfers (acc_nr, amount, reference) VALUES (254231426, -100.00, ’Dentist’);

INSERT INTO transfers (acc_nr, amount, reference) VALUES (676535301, 100.00, ’John Smith’);

COMMIT;

 

同時事務:

復雜情況:多種同時事務

情況1:按順序執行事務

  很簡單去實行,在一些情況下工作的很好

  但是有時過慢了:

    CPU可以保持空閑當I/O轉換過程中,反之亦然

    慢的語句可能會阻礙快的那個

    事務可能需要去等待用戶輸入

情況2:事務的交錯執行

  等待時間一半都減少特別明顯了

  在單命令事務中也能進行工作(分裂成多種更小的操作)

  但是難以正確實施進行

  這就是DBMS所做的事

 

ACID規則:

ACID規則是擺正多個并行事務能被可靠處理的一組方法策略

Atomicity:原子性   Consistency:一致性   Isolation:交易之間不被相互作用     Durability:持久性

復雜的是隔離或可串行化的:確保并行執行相當于對某個順序的順序執行。

這就是并發控制的全部內容。

注意:為了保持DB編程的可管理性,DBMS確保串行化是至關重要的,想象一下擔心其他查詢會妨礙運行的任何查詢!

 

并發控制:

查詢被分成許多較小的操作。

允許對這些操作進行交錯。

啟用并發性

 

但如果使用相同的數據,則會出現問題。

不能更新(Lost Update)

不好識別(Dirty Reads)

不能一致識別(Inconsistent Reads)

 

并發控制的目的:

允許通用的并發,但禁止危險的相互作用。

 

Lost update:

假設有人花了50,并得到了2000,兩個事務是同時發生的

語句則被分成很多帶順序的低級操作:

下面是交錯操作:

這種方式下在賬戶里增加2000的效率丟失了

 

Dirty Reads

當事務讀取由另一事務修改的值時,會發生Dirty Reads,但修改不是最終的。

交錯操作如下:

返回余額0,即便已經被回滾了

 

Inconsistent Reads

不一致(不可重復)的讀取 發生在在另一事務之間改變時讀值多次

交錯操作如下:

最大余額的賬戶尋找不到

 

讀/寫鎖

目標:

防止對同一數據的并發訪問

但要盡量減少對性能的影響

只在必要時限制以防止問題

 

區分讀寫操作/訪問

交錯讀取操作是無害的。

交錯寫入操作會引起問題。

交錯讀寫操作也會引起問題。

 

兩種鎖:

讀鎖(又名共享鎖)

寫鎖(又名專用鎖)

可以有多個讀鎖或單個寫鎖

 

在事務訪問數據之前,它必須獲取鎖,如果不可能,稍后再嘗試

鎖定可以在不同級別下發生:數據庫級,表級,頁面級別(最常見),行級

 

數據庫級別:只需要單個鎖,但不并發

行級:大并發,但需要的鎖太多

表和頁級鎖提供了一個折衷方案

 

多查詢事務隨時間獲取鎖,在需要時獲得很容易。

但是什么時候釋放它們呢?

越快越好并發,但有問題

那么,如果我們釋放一個鎖,然后又需要它會發生什么?

那么,如果我們釋放一個鎖,然后需要一個不同的鎖會發生什么?

二相鎖定協議

成長階段:獲取鎖(無鎖釋放)  收縮階段:釋放鎖(沒有獲得的鎖)也就是在事務結束時釋放所有鎖

防止有問題的操作交錯

兩階段鎖定(帶表級鎖):

死鎖(Deadlocks)

兩個事務可能互相等待釋放鎖。

  因為兩者都在等待,沒有一個釋放他們的鎖。

  也可以發生兩個以上的事務,這種僵局被稱為僵局。

  兩相鎖定不能防止死鎖

死鎖可以用不同的方式處理:

死鎖預防:

  如果發生僵局,就采取行動

  可能不必要中止交易

死鎖檢測:

   如果發生死鎖,只能采取行動

  用于檢測死鎖的開銷

額外的問題:饑餓

為了解決死鎖,事務需要中止(如果可能的話重新開始)

相同的事務可能會一再中止(它“餓死”了)。

解決方案:總是中止上次提交的事務

  所有的事務都是時間戳的。

  當中止并重新啟動時,保留原始時間戳。

 

死鎖預防:

等待-死亡方案:

如果T1需要一個T2持有的鎖:

(等待)如果T1大于T2,等待鎖定被釋放。

(死亡)如果T1較小,中止T1并稍后重啟。

 

傷口等待方案:如果T1需要一個T2持有的鎖:

(受傷)如果T1大于T2,則中止T2并重新啟動。

(等待)如果T1較小,等待鎖定被釋放。

 

兩種方案的共同點:

死鎖被解決的了

年輕的過程中止了——沒有饑餓

即使沒有死鎖,事務也可能中止

 

死鎖檢測:

目標:只有死鎖發生時才會中止

 

構造和維護等待圖

每個事務都是一個節點。

如果Ti在等待Tj持有的鎖,則從TI到TJ的有向邊。

如果圖包含任何循環,則為死鎖。如果檢測到循環,則中止一個事務以中斷循環 例如:最年輕的交易——沒有饑餓。

維護等待圖和檢測周期是昂貴的

最適合于很少并發事務的數據庫,或者當重新啟動事務是有問題的(例如中間結果已經返回)

 

死鎖解析由DBMS處理,但并非所有的實現都能防止饑餓。,頻繁死鎖減速處理(DBMS可能需要一些幫助)

謹慎地構造交易可以減少僵局:

  提前鎖定(在事務開始時),減少鎖定操作交錯的機會

  以固定順序獲取所有事務的鎖,防止死鎖,但對于大的代碼庫是困難的

在每種情況下,都必須聲明所需的鎖。

DBMS提供用于獲取/釋放鎖的工具

 

DBMSs還允許禁用/減弱鎖定,防止/減少死鎖,加快查詢速度,但能制造出不可復制的討厭的bugs

在大多數情況下,這是個壞方法!

----------------------------------------------------

頻繁類型的死鎖:先讀取數據,然后更新

許多DBMS提供更新鎖來處理這個問題。

只允許讀取數據

不能有多個更新鎖(或更新+寫鎖),防止上述類型的死鎖

允許單個更新鎖+多個讀鎖,不阻止讀寫鎖定

必須由用戶明確聲明,例如

 

 

數據庫恢復

當事務中止時,必須進行更改。

事務被終止可能由于

  用戶發出的顯式回滾

  死鎖、超時或錯誤

  數據庫管理系統崩潰

在DBMS崩潰的情況下,我們需要確保

  所有未提交的事務都會回滾。

  所有已提交事務的更改被保存。

更新通常只在內存中執行,更快,但在DBMS崩潰期間丟失

 

事務日志

所有數據修改都記錄在事務日志中。

  存儲“前后”和“后”值

  允許改變顛倒

  必須在數據更改之前發生日志記錄。(日志沒有變化是可以的,沒有日志的更改是壞的)

元數據也存儲在事務日志中。

  事務的開始/結束(提交或回滾)

  檢查點(從內存保存到磁盤的數據),可以識別哪些更新丟失了

當DBMS崩潰時,重新啟動它

  讀取事務日志

  標識未提交的事務并將它們滾回。

  識別并重新應用已提交事務的丟失更新

dB以一致狀態(原子性)開始。

所有承諾的事務持續(持久性)

 

Summary

事務將數據庫命令分組為單元

ACID確保DB相互作用是可靠的

交錯操作對性能至關重要。

  為了保證隔離,需要進行并發控制

  鎖定數據會導致死鎖

  解決僵局的協議(DBMS),

  最小化死鎖的技術(用戶)

使用事務日志的數據庫恢

相關教程