摘要:前言前面關系數據庫之可編程性函數用戶自定義函數一文提到關系型數據庫提供了可編程性的函數存儲過程事務觸發器及游標,前文已介紹了函數存儲過程,本文來介紹一下事務的使用。在相關數據庫中,所有規則都必須應用于事務的修改,以保持所有數據的完整性。
前言
前面關系數據庫SQL之可編程性函數(用戶自定義函數)一文提到關系型數據庫提供了可編程性的函數、存儲過程、事務、觸發器及游標,前文已介紹了函數、存儲過程,本文來介紹一下事務的使用。(還是以前面的銀行系統為例)
概述語法是指作為單個邏輯工作單元執行的一系列操作,要么完全地執行,要么完全地不執行。
一個邏輯工作單元要成為事務,必須滿足所謂的ACID(原子性、一致性、隔離性和持久性)特性。
開始事務:事務開始的位置,就是單個邏輯工作單元的開始。
回滾事務:就是將數據恢復至事務開始的狀態,一般是不滿足條件或者是發生錯誤的時候執行該操作。
提交事務:事務結束的位置,就是單個邏輯工作單元成功執行后,改變數據狀態。
--開始事務 BEGIN TRAN[SACTION] --回滾事務,TRAN[SACTION]可省略 ROLLBACK TRAN[SACTION] --提交事務 COMMIT TRAN[SACTION] --事務使用 BEGIN TRAN[SACTION] --這里是SQL語句塊
上面的SQL語句塊,需要在適當的位置加上COMMIT TRAN[SACTION],如果需要回滾可以有ROLLBACK TRAN[SACTION]。
事務可以與存儲過程聯合使用。
特性原子性(Atomic)(Atomicity)
事務必須是原子工作單元;對于其數據修改,要么全都執行,要么全都不執行。通常,與某個事務關聯的操作具有共同的目標,并且是相互依賴的。如果系統只執行這些操作的一個子集,則可能會破壞事務的總體目標。原子性消除了系統處理操作子集的可能性。
一致性(Consistent)(Consistency)
事務在完成時,必須使所有的數據都保持一致狀態。在相關數據庫中,所有規則都必須應用于事務的修改,以保持所有數據的完整性。事務結束時,所有的內部數據結構(如 B 樹索引或雙向鏈表)都必須是正確的。某些維護一致性的責任由應用程序開發人員承擔,他們必須確保應用程序已強制所有已知的完整性約束。例如,當開發用于轉帳的應用程序時,應避免在轉帳過程中任意移動小數點。
隔離性(Insulation)(Isolation)
由并發事務所作的修改必須與任何其它并發事務所作的修改隔離。事務查看數據時數據所處的狀態,要么是另一并發事務修改它之前的狀態,要么是另一事務修改它之后的狀態,事務不會查看中間狀態的數據。這稱為隔離性,因為它能夠重新裝載起始數據,并且重播一系列事務,以使數據結束時的狀態與原始事務執行的狀態相同。當事務可序列化時將獲得最高的隔離級別。在此級別上,從一組可并行執行的事務獲得的結果與通過連續運行每個事務所獲得的結果相同。由于高度隔離會限制可并行執行的事務數,所以一些應用程序降低隔離級別以換取更大的吞吐量。
持久性(Duration)(Durability)
示例事務完成之后,它對于系統的影響是永久性的。該修改即使出現致命的系統故障也將一直保持。
創建一個帶事務的存儲過程:孫悟空要取錢,交易信息表里面插入交易信息,同時要更改賬戶表里面的余額
begin transaction if exists(select * from sysobjects where name = "proc_getMoney") drop procedure proc_getMoney go create proc proc_getMoney @cardId varchar(19), @tranMoney money as declare @balance money select @balance = LeftMoney from CardInfo where CardID = @cardId if(@tranMoney <= @balance) begin insert into TransInfo values(@cardId,"取款",@tranMoney,default) if(@@ERROR=0) begin update CardInfo set LeftMoney = LeftMoney - @tranMoney where CardID = @cardId if(@@ERROR=0) begin commit transaction print "OK" end end else begin rollback print "error" end end else print "余額不足" go exec proc_getMoney "1324 3626 7532 1935",520 go exec proc_getMoney "1027 3526 1536 1135",520 go
在存儲過程內創建事務,根據用戶輸入的個人信息,實現銀行卡開戶,輸出參數作為用戶的銀行卡卡號以及銀行卡余額(開戶時不僅要在用戶信息表和銀行卡表添加一條數據,也要在交易信息表中插入一條存款的記錄,因為開卡時需要指定開卡金額,銀行卡卡號自動生成)
if exists(select * from sysobjects where name = "proc_openAccount") drop procedure proc_openAccount go create proc proc_openAccount @CustName varchar(20), --定義變量開戶人姓名 @IDCard varchar(18), --定義變量開戶人身份證號 @TelePhone varchar(13), --定義變量開戶人電話號碼 @Address varchar(50), --定義變量開戶人住址 @openMoney money --定義變量開戶存入現金金額 as begin begin transaction declare @CustID int,@CardID varchar(19) --定義變量開戶人的賬戶編號,開戶的卡號 exec proc_getCardNo @CardID output --執行自動生成卡號的存儲過程,將輸出值賦給變量@CardID --向賬戶表中插入數據 insert into AccountInfo values (@CustName,@IDCard,@TelePhone,@Address) if(@@error != 0)--如果出錯 rollback--事務回滾 else begin set @CustID = @@identity --獲取生成賬戶的編號CustID --向銀行卡表中插入數據 insert into CardInfo values (@CardID,default,@CustID,"活期",getdate(),@openMoney,@openMoney,"否") if(@@error != 0) rollback else begin --向交易表中插入數據 insert into TransInfo values (@CardID,"存款",@openMoney,default) if(@@error != 0) begin rollback print "開戶失敗,插入數據錯誤!" end else begin print "開戶成功!" print "卡號為:" + @CardID end end end commit transaction end go exec proc_openAccount "八戒","422322001550135015","027-8658888","高老莊",250 go
附:
實現生產銀行卡的存儲過程,該存儲過程能隨機的產生一個卡號輸出
if exists(select * from sysobjects where name = "proc_getCardNo") drop procedure proc_getCardNo go create proc proc_getCardNo @CardNo varchar(19) output --定義輸出參數的類型 as begin declare @day varchar(2) --定義日期 set @day = dateName(dd,getdate()) if @day<10 --如果日期小于10,要對其加"0" set @day = "0"+@day set @CardNo = convert(varchar(9),(dateName(yyyy,getdate())+" " + dateName(mm,getdate())))+@day+" "+ convert(varchar(10),(dateName(hh,getdate()) +dateName(mi,getdate())+" "+ subString(convert(varchar(6),rand(datepart(ms,getdate()))*1000000),1,5))) end go declare @card varchar(19) exec proc_getCardNo @card output print "卡號為:" + @card go
本文就介紹到這里。
如有疑問請聯系我。
原文來自:簡書
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/17538.html
摘要:前言前面關系數據庫之可編程性函數用戶自定義函數一文提到關系型數據庫提供了可編程性的函數存儲過程事務觸發器及游標,前文已介紹了函數存儲過程事務,本文來介紹一下觸發器的使用。觸發器是在執行之后觸發,而觸發器是在執行之前觸發。 前言 前面關系數據庫SQL之可編程性函數(用戶自定義函數)一文提到關系型數據庫提供了可編程性的函數、存儲過程、事務、觸發器及游標,前文已介紹了函數、存儲過程、事務,本...
閱讀 853·2019-08-30 15:54
閱讀 3322·2019-08-29 15:33
閱讀 2707·2019-08-29 13:48
閱讀 1226·2019-08-26 18:26
閱讀 3339·2019-08-26 13:55
閱讀 1489·2019-08-26 10:45
閱讀 1173·2019-08-26 10:19
閱讀 312·2019-08-26 10:16