看看這個網上流傳的“sql server 事務舉例”

來源:互聯網
上載者:User
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

這個在網上流傳的預存程序事務舉例我也用過,可是今天拿出來一看,已經提交的事務還能復原嗎?

從直觀上就是錯誤的,俺以為其中另有“隱情”,於是作了個測試,測試代碼如下:

先建了一個表,並向其中添加了約束:

USE [test]
GO
/****** 對象:  Table [dbo].[salary]    指令碼日期: 12/12/2007 14:24:47 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[salary](
 [id] [int] IDENTITY(1,1) NOT NULL,
 [salary] [real] NULL
) ON [PRIMARY]

GO
ALTER TABLE [dbo].[salary]  WITH NOCHECK ADD  CONSTRAINT [t1] CHECK  (([salary]>=(1) AND [salary]<=(1)))
GO
ALTER TABLE [dbo].[salary] CHECK CONSTRAINT [t1]

然後建立了一個預存程序:

USE [test]
GO
/****** 對象:  StoredProcedure [dbo].[tt]    指令碼日期: 12/12/2007 14:25:44 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:  <風景年華>
-- Create date: <2007-12-12>
-- Description: <test>
-- =============================================
CREATE PROCEDURE [dbo].[tt]
 -- Add the parameters for the stored procedure here
AS
BEGIN
 -- SET NOCOUNT ON added to prevent extra result sets from
 -- interfering with SELECT statements.
 SET NOCOUNT ON;

    -- Insert statements for procedure here
 begin tran
  save tran test
  insert salary values (5)
 
 if (@@error<>0)
  begin
   print '111'
   rollback tran test
  end
 commit tran

 END

再建一個預存程序:

USE [test]
GO
/****** 對象:  StoredProcedure [dbo].[tt]    指令碼日期: 12/12/2007 14:25:44 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:  <風景年華>
-- Create date: <2007-12-12>
-- Description: <test>
-- =============================================
CREATE PROCEDURE [dbo].[tt1]
 -- Add the parameters for the stored procedure here
AS
BEGIN
 -- SET NOCOUNT ON added to prevent extra result sets from
 -- interfering with SELECT statements.
 SET NOCOUNT ON;

    -- Insert statements for procedure here
 begin tran
  save tran test
  insert salary values (5)
 
  commit tran

if (@@error<>0)
  begin
   print '111'
   rollback tran test
  end

 END

兩次測試結果:
1.

訊息 547,層級 16,狀態 0,過程 tt,第 17 行
INSERT 語句與 CHECK 條件約束"t1"衝突。該衝突發生於資料庫"test",表"dbo.salary", column 'salary'。
語句已終止。
111

(1 行受影響)

結果中輸出了  111

2.

訊息 547,層級 16,狀態 0,過程 tt1,第 17 行
INSERT 語句與 CHECK 條件約束"t1"衝突。該衝突發生於資料庫"test",表"dbo.salary", column 'salary'。
語句已終止。

(1 行受影響)

結果中沒有輸出  111  表明沒有執行預存程序

測試環境:sql  server  2005 express

這是另外一個樣本:

1,SqlServer預存程序的交易處理
一種比較通用的出錯處理的模式大概如下:
Create procdure prInsertProducts
(
 @intProductId int,
 @chvProductName varchar(30),
 @intProductCount int
)
AS
Declare @intErrorCode int
Select @intErrorCode=@@Error
Begin transaction
 if @intErrorCode=0
   begin
     -insert products
     insert products(ProductID,ProductName,ProductCount)
     s(@intProductId,@chvProductName,@intProductCount)
     Select @intErrorCode=@@Error --每執行完一條t-sql語句馬上進行檢測,並把錯誤號碼儲存到局部變數中
   end
 if @intErrorCode=0
   begin
     -update products
     update products set ProductName='MicroComputer' where ProductID=5
     Select @intErrorCode=@@Error
   end
if @intErrorCode=0
   commit transaction
else
   rollback transaction

 Return @intErrorCode --最好返回錯誤代號給調用的預存程序或應用程式

2,.Net中使用交易處理
SqlConnection myConnection = new SqlConnection("Data Source=localhost;Initial Catalog=Northwind;Integrated Security=SSPI;");
myConnection.Open();

SqlTransaction myTrans = myConnection***ginTransaction(); //使用New新產生一個事務
SqlCommand myCommand = new SqlCommand();
myCommand.Transaction = myTrans;

try
{
myCommand.CommandText = "Update Address set location='23 rain street' where userid='0001'";
myCommand.ExecuteNonQuery();
myTrans.Commit();
Console.WriteLine("Record is udated.");
}
catch(Exception e)
{
myTrans.Rollback();
Console.WriteLine(e.ToString());
Console.WriteLine("Sorry, Record can not be updated.");
}
finally
{
myConnection.Close();
}

說明:在SqlServer中,每條Sql語句都作為一個事務來執行,所以無論在預存程序,還是在.net代碼中使用,執行單條Sql語句沒有必要使用交易處理,上面只是為了簡化表達而對單條Sql語句使用交易處理

這就是俺的測試  初學sql  歡迎拍轉

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.