一、錯誤處理
1. 處理方法
- sys.messages定義內置錯誤號和錯誤消息
- @@ERROR記錄了執行每一條語句後的錯誤號
二者結合就可以從sys.messages中找到錯誤號=@@EEROR的錯誤消息
2.TRY…CATCH
自定義處理錯誤,錯誤不再由系統拋出
begin try
print 'before'
select 1/0
print 'after'
end try
begin catch
select text
from sys.messages
where language_id=2052 --2052是設置錯誤消息爲簡體中文,1033是設置爲英文
and message_id=@@error
end catch
運行結果:
3.自定義錯誤
- 定義持久化錯誤
EXECUTE sp_addmessage 錯誤號,錯誤級別,錯誤消息,'us_english'
如果是中文版SQL Server,需要在錯誤消息後添加’us_english’ - 直接拋出錯誤,默認50000號錯誤
- 通過
RAISERROR(錯誤號|錯誤消息,錯誤級別,狀態);
主動拋出錯誤
EXECUTE sp_addmessage 233333,10,'A defined error','us_english';
RAISERROR (233333,10,1);
RAISERROR ('This is a tmp error',10,1);
運行結果:
- 用戶自定的錯誤號應當大於50000
- 錯誤消息最長2047個字符
- 用戶可以定義0-18的錯誤級別。錯誤級別在[0,10]內不會跳到catch,在[11,19]跳到catch,在[20,25]直接終止數據庫連接
- 狀態號爲0-255的整數,負值默認爲1。在多個位置引發相同的用戶定義錯誤可以用狀態號找到引發錯誤的代碼
二、事務
事務成功所有數據修改都會提交,事務錯誤必須取消或者回滾,所有數據修改被清楚
事務主要面向多用戶的併發訪問。
事務的四個基本要素:ACID
- Atomicity原子性:所有操作要麼成功提交要麼完全回滾
- Consistency一致性:業務邏輯一致,數據約束完整
- Isolation隔離性:事務間加鎖隔離,控制可見度
- Durability持久性:完成後的事務持久保存在數據庫中,不會被回滾
1、原子性
TCL語法實現:
begin try
begin transaction T:
insert into test values (1,2);
insert into test values (2,3);
save transaction S;
--主鍵衝突
insert into test values (1,3);
insert into test values (2,4);
commit transaction T;
end try
begin catch
rollback transaction S;
commit transaction T;
end catch
運行結果:
2、獨立性
- 共享鎖S:讀鎖
- 排他鎖、獨佔鎖X:寫鎖
- 更新鎖U:用於批量UPDATE,讀取階段類似S,修改階段類似X
- 意向鎖I:對鎖作標記的假鎖,用於自適應式鎖升級
有S鎖不可寫
有X鎖不可讀寫
當有人讀取數據時放置共享鎖,另一個人讀取數據時由於共享鎖彼此不互斥,所以可以再次放置共享鎖。而當有人要更新記錄,獨佔鎖和共享鎖互斥,無法放置獨佔鎖。必須等到所有人讀取數據完畢,釋放共享鎖後才能更新數據。
ANSI隔離層級標準:
-
讀取時未提交:不使用鎖
會看見其他事務未提交的修改,如之後rollback取消修改;髒讀
-
讀取已提交(默認隔離層級):讀取時無X鎖
可見已提交的數據值修改,修改後再次讀數據變化;不可重複讀
可見已提交的記錄數修改,插入後再次讀數據數量變化:幻讀
-
可重複讀:讀時加有限範圍的S鎖並保持
避免不可重複讀
-
可序列化:讀時全事務範圍的S鎖並保持
避免任何讀問題
死鎖:
兩個或多個會話互相請求對方持有的鎖資源,導致循環等待的情況
四個必要條件:
-
互斥:一個資源只能被一個進程使用
-
請求與保持:一個進程因請求資源而阻塞時,已獲得的資源保持不放
-
不剝奪:進程已獲得的資源,在未使用完前不能強行剝奪
-
循環等待:若干進程之間形成一種頭尾相接的循環等待資源關係
3.一致性/持續性
通過日誌實現duouxingxie
預寫日誌WAL,惰性寫LW
WAL的災難恢復通過由早到晚順序Redo已提交卻未寫入主數據文件的數據和由晚到早逆序Undo未提交卻已寫入日誌文件的數據