1、實際問題sql
問:怎麼保證兩條SQL語句同時執行成功或者同時執行失敗?數據庫
答:使用事務來保證。數據結構
2、舉例說明併發
---例子:一我的要給另外一人轉帳,假設0001號用戶只有100塊錢,0002號用戶有50塊錢索引
-- bank表字段cid、balance事務
-- 從 0002用戶減去100元>50元,顯然是要出錯,錢不會減小。
update bank set balance=balance-100 where cid='0002'ci
-- 給0001用戶增長100元,可是0001用戶缺神奇的多了100元!it
update bank set balance=balance + 100 where cid='0001'io
-- 若是sql語句執行過程當中一條失敗了另外一條成功了,那銀行就很糟糕!date
--解決:經過把兩個sql語句放到一個事務裏,若是任何一條語句發生失敗,會回滾到事務內SQL語句執行前的狀態。
--步驟:
--1.打開一個事務
begin transaction
declare @sum int =0
--2 執行SQL語句
update bank set balance=balance-100 where cid='0002'
set @sum=@sum+@@error ----在轉帳以前最好經過if-else判斷,不要讓程序發生異常或者錯誤!
update bank set balance=balance + 100 where cid='0001'
set @sum=@sum+@@error
--3 判斷,若是有任何一條SQL語句執行出錯,那麼@@error就不會返回0
if @sum<>0
begin
rollback --4失敗則回滾
end
else
begin
commit --5成功,則提交
end
--注意:實際工做中杜絕拋出異常,要把全部的異常都判斷到,消滅在if-else中。
3、事務類型:
--1全自動提交事務
--當執行一條sql語句的時候,數據庫自動幫咱們打開一個事務,當語句執行成功,數據庫自動提交事務,執行失敗,數據庫自動回滾事務。
--insert into bbbb values(fsd) --這條sql語句內部實際就有一個事務。
--2隱式事務,每次執行一條sql語句的時候,數據庫自動幫咱們打開一個事務,可是須要咱們手動提交事務,或者回滾事務。
SET IMPLICIT_TRANSACTIONS { ON | OFF }隱式事務
--打開隱式事務 :自動打開事務,手動提交或回滾事務
SET IMPLICIT_TRANSACTIONS ON
insert into bank values('0003',1000000)
commit
SET IMPLICIT_TRANSACTIONS off
--3顯示事務:須要手動打開事務,手動提交事務或者回滾事務。
begin tran --...... commit tran --- rollback transaction ------(如上面的例子)
4、事務的特性
事務是做爲單個邏輯工做單元執行的一系列操做。一個邏輯工做單元必須有四個屬性,稱爲原子性、一致性、隔離性和持久性 (ACID) 屬性,只有這樣才能成爲一個事務。1原子性 事務必須是原子工做單元;對於其數據修改,要麼全都執行,要麼全都不執行。2一致性 事務在完成時,必須使全部的數據都保持一致狀態。在相關數據庫中,全部規則都必須應用於事務的修改,以保持全部數據的完整性。事務結束時,全部的內部數據結構(如 B 樹索引或雙向鏈表)都必須是正確的。3隔離性 由併發事務所做的修改必須與任何其餘併發事務所做的修改隔離。事務識別數據時數據所處的狀態,要麼是另外一併發事務修改它以前的狀態,要麼是第二個事務修改它以後的狀態,事務不會識別中間狀態的數據。這稱爲可串行性,由於它可以從新裝載起始數據,而且重播一系列事務,以使數據結束時的狀態與原始事務執行的狀態相同。4持久性 事務完成以後,它對於系統的影響是永久性的。該修改即便出現系統故障也將一直保持。