事務全攻略

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk= watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=Code
CREATE PROCEDURE testPro
AS
    /**//* ------- 事務開始 ---------- */
    BEGIN TRANSACTION tran_test

    /**//* -------- 保存事務 ----------*/
    SAVE TRANSACTION tran_test

        /**//* -------- 數據操做 ---------*/
        INSERT [table1] ( [content] ) VALUES ( '43332' )

    /**//*---------- 提交事務 ------------*/
    COMMIT TRANSACTION tran_test

    /**//*--------- 判斷是否有錯誤 ----------*/
    IF ( @@ERROR <> 0 )
    BEGIN
        /**//*---------- 自定義錯誤輸出 ----------*/
        RAISERROR( 'Insert data error!',16,1 )
        /**//*-------- 事務回滾 --------*/
        ROLLBACK TRANSACTION tran_test
    END
    
    /**//*------- 判斷事務數是否大於0 -----------*/
    IF ( @@TRANCOUNT > 0 )
    BEGIN
        /**//*-------- 事務回滾 --------*/
        ROLLBACK TRANSACTION tran_test
    END
GO

 

事務具備ACID屬性sql

Atomic原子性, Consistent一致性, Isolated隔離性, Durable永久性數據庫

 

原子性  服務器

   就是事務應做爲一個工做單元,事務處理完成,全部的工做要麼都在數據庫中保存下來,要麼徹底回滾,所有不保留併發

 

一致性分佈式

   事務完成或者撤銷後,都應該處於一致的狀態ide

 

隔離性spa

   多個事務同時進行,它們之間應該互不干擾.應該防止一個事務處理其餘事務也要修改的數據時,不合理的存取和不完整的讀取數據調試

 

永久性orm

   事務提交之後,所作的工做就被永久的保存下來server

1.2.        事務併發處理會產生的問題

丟失更新

    當兩個或多個事務選擇同一行,而後基於最初選定的值更新該行時,會發生丟失更新問題、每一個事務都不知道其它事務的存在。最後的更新將重寫由其它事務所作的更新,這將致使數據丟失。

 

髒讀

     當第二個事務選擇其它事務正在更新的行時,會發生未確認的相關性問題。

     第二個事務正在讀取的數據尚未確認而且可能由更新此行的事務所更改。

 

不可重複讀

     當第二個事務屢次訪問同一行並且每次讀取不一樣的數據時,會發生不一致的分析問題。

     不一致的分析與未確認的相關性相似,由於其它事務也是正在更改第二個事務正在讀取的數據。

     然而,在不一致的分析中,第二個事務讀取的數據是由已進行了更改的事務提交的。並且,不一致的分析涉及屢次(兩次或更多)讀取同一行,並且每次信息都由其它事務更改;於是該行被非重複讀取。

 

幻像讀

      當對某行執行插入或刪除操做,而該行屬於某個事務正在讀取的行的範圍時,會發生幻像讀問題。

      事務第一次讀的行範圍顯示出其中一行已不復存在於第二次讀或後續讀中,由於該行已被其它事務刪除。一樣,因爲其它事務的插入操做,事務的第二次或後續讀顯示有一行已不存在於原始讀中。

1.3.        事務處理類型

自動處理事務

   系統默認每一個TSQL命令都是事務處理  由系統自動開始並提交

 

隱式事務

    當有大量的DDL DML命令執行時會自動開始,並一直保持到用戶明確提交爲止,切換隱式事務能夠用SET IMPLICIT_TRANSACTIONS爲鏈接設置隱性事務模式.當設置爲 ON 時,SET IMPLICIT_TRANSACTIONS 將鏈接設置爲隱性事務模式。當設置爲 OFF 時,則使鏈接返回到自動提交事務模式

 

用戶定義事務

     由用戶來控制事務的開始和結束  命令有: begin tran commit tran  rollback tran 命令

 

分佈式事務

     跨越多個服務器的事務稱爲分佈式事務,sql server 能夠由DTc microsoft distributed transaction coordinator來支持處理分佈式事務,可使用 BEgin distributed transaction 命令啓動一個分佈式事務處理。

1.4.        事務處理的隔離級別

使用SET TRANSACTION ISOLATION LEVEL來控制由鏈接發出的全部語句的默認事務鎖定行爲

從低到高依次是:

 

READ UNCOMMITTED

執行髒讀或 0 級隔離鎖定,這表示不發出共享鎖,也不接受排它鎖。當設置該選項時,能夠對數據執行未提交讀或髒讀;在事務結束前能夠更改數據內的數值,行也能夠出如今數據集中或從數據集消失。該選項的做用與在事務內全部語句中的全部表上設置 NOLOCK 相同。這是四個隔離級別中限制最小的級別。

舉例

table1(A,B,C)

A    B    C

a1   b1   c1

a2   b2   c2

a3   b3   c3

 

新建兩個鏈接

在第一個鏈接中執行如下語句

select * from table1

begin tran

update table1 set c='c'

select * from table1

waitfor delay '00:00:10'  --等待10秒

rollback tran

select * from table1

 

在第二個鏈接中執行如下語句

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

print '髒讀'

select * from table1

if @@rowcount>0

begin

 waitfor delay '00:00:10'

 print '不重複讀'

 select * from table1

en

第二個鏈接的結果

髒讀

A    B    C

a1   b1   c

a2   b2   c

a3   b3   c

 

'不重複讀'

A    B    C

a1   b1   c1

a2   b2   c2

a3   b3   c3

 

READ COMMITTED

指定在讀取數據時控制共享鎖以免髒讀,但數據可在事務結束前更改,從而產生不可重複讀取或幻像數據。該選項是 SQL Server 的默認值。

 

在第一個鏈接中執行如下語句

SET TRANSACTION ISOLATION LEVEL READ COMMITTED

begin tran

print '初始'

select * from table1

waitfor delay '00:00:10'  --等待10秒

print '不重複讀'

select * from table1

rollback tran

在第二個鏈接中執行如下語句

SET TRANSACTION ISOLATION LEVEL READ COMMITTED

update table1 set c='c'

第一個鏈接的結果

初始

A    B    C

a1   b1   c1

a2   b2   c2

a3   b3   c3

 

不重複讀

A    B    C

a1   b1   c

a2   b2   c

a3   b3   c

 

REPEATABLE READ

鎖定查詢中使用的全部數據以防止其餘用戶更新數據,可是其餘用戶能夠將新的幻像行插入數據集,且幻像行包括在當前事務的後續讀取中。由於併發低於默認隔離級別,因此應只在必要時才使用該選項。

 

在第一個鏈接中執行如下語句

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ

begin tran

print '初始'

select * from table1

waitfor delay '00:00:10'  --等待10秒

print '幻像讀'

select * from table1

rollback tran

在第二個鏈接中執行如下語句

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ

insert  table1 select 'a4','b4','c4'

第一個鏈接的結果

初始

A    B    C

a1   b1   c1

a2   b2   c2

a3   b3   c3

 

幻像讀

A    B    C

a1   b1   c1

a2   b2   c2

a3   b3   c3

a4   b4   c4

 

 

SERIALIZABLE

在數據集上放置一個範圍鎖,以防止其餘用戶在事務完成以前更新數據集或將行插入數據集內。這是四個隔離級別中限制最大的級別。由於併發級別較低,因此應只在必要時才使用該選項。該選項的做用與在事務內全部 SELECT 語句中的全部表上設置 HOLDLOCK 相同。

 

在第一個鏈接中執行如下語句

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE

begin tran

print '初始'

select * from table1

waitfor delay '00:00:10'  --等待10秒

print '沒有變化'

select * from table1

rollback tran

 

 

在第二個鏈接中執行如下語句

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE

insert  table1 select 'a4','b4','c4'

 

第一個鏈接的結果

初始

A    B    C

a1   b1   c1

a2   b2   c2

a3   b3   c3

 

沒有變化

A    B    C

a1   b1   c1

a2   b2   c2

a3   b3   c3

1.5.        事務處理嵌套語法和對@@TRANCOUNT的影響

l         Ø   BEGIN TRAN           @@TRANCOUNT1

l         Ø   COMMIT TRAN        @@TRANCOUNT1

l         Ø   ROLLBACK TRAN     使@@TRANCOUNT迴歸0

l         Ø   SAVE TRAN             不影響@@TRANCOUNT

例一

SELECT '事務處理前', @@TRANCOUNT      --值爲 0

BEGIN TRAN

  SELECT '第一個事務', @@TRANCOUNT      --值爲 1

    SELECT * FROM table1

    BEGIN TRAN

       SELECT '第二個事務', @@TRANCOUNT  --值爲 2

         DELETE table1

    COMMIT TRAN

    SELECT '遞交第二個事務', @@TRANCOUNT --值爲 1

ROLLBACK TRAN

SELECT '回滾第一個事務', @@TRANCOUNT --值爲 0

 

例二

SELECT '事務處理前', @@TRANCOUNT      --值爲 0

BEGIN TRAN

  SELECT '第一個事務', @@TRANCOUNT    --值爲 1

    SELECT * FROM table1

  SAVE TRAN t1

  SELECT '保存第一個事務後', @@TRANCOUNT --值爲 1

    BEGIN TRAN

       SELECT '第二個事務', @@TRANCOUNT  --值爲 2

         DELETE table1

   ROLLBACK TRAN t1

    SELECT '回滾到保存點t1', @@TRANCOUNT --注意這裏的值爲 2

IF @@TRANCOUNT>0

ROLLBACK TRAN

SELECT '處理結束', @@TRANCOUNT --爲 0

 

SET XACT_ABORT

控制語句產生運行時錯誤時,是否自動回滾當前事務

好比

SET XACT_ABORT ON

BEGIN TRAN

  SELECT * FROM 一個不存在的表

ROLL BACKTRAN

PRINT '處理完畢'  --執行結果沒有到這一步

go

SELECT @@TRANCOUNT  --值爲1 產生孤立事務

1.6.        事務調試語句

DBCC OPENTRAN

若是在指定數據庫內存在最舊的活動事務和最舊的分佈和非分佈式複製事務,則顯示與之相關的信息。

示例

下例得到當前數據庫和 pubs 數據庫的事務信息。

-- Display transaction information only for the current database.

DBCC OPENTRAN

GO

-- Display transaction information for the pubs database.

DBCC OPENTRAN('pubs')

GO

1.7.        事務嵌套的例子

1) 若是內層事務出錯就取消全部事務

BEGIN TRAN t1

 

   UPDATE tablename SET colname='37775' WHERE id='140'

      

 BEGIN TRAN  t2

 

   UPDATE tablename SET colname='37775' WHERE id='140' --id不存在

 

     IF (@@rowcount=0)

         BEING

           ROLLBAKC TRAN

          END

      ELSE

          BEGIN

            COMMIT TRAN  t2

            COMMIT TRAN  t1

          END

2) 事務處理中只要有一個出錯就回滾

BEGIN TRAN

      UPDATE tablename SET colname='37775' WHERE id=170

        IF ( @@rowcount=0 )

          ROLLBACK TRAN

      UPDATE tablename SET colname='37775' WHERE id=870  --此id不存在

        IF ( @@rowcount=0 )

          ROLLBACK TRAN

3) 有關循環處理事務的問題,要求循環處理中,若是一個條件不知足就取消全部循環

DECLARE @id INT

SET  @id=1

 

WHILE (@id<280)

--注表中實際id最大爲260,因此此循環執行到@id=261 update語句就沒有做用了

 

 BEGIN

   BEGIN TRAN

    UPDATE tablename SET colname='37775' WHERE id=@id

     IF ( @@rowcount=0 )

          ROLLBACK TRAN

    SET  @id=@id+1

  END

相關文章
相關標籤/搜索