在存储过程中编写正确的事务处理代码

在 SQL Server 中数据库事务处理是个重要的概念,也稍微有些不容易理解,很多 SQL 初学者编写的事务处理代码存往往存在漏洞,

本文介绍了三种不同的方法,举例说明了如何在存储过程事务处理中编写正确的代码。

在编写 SQL Server 事务相关的存储过程代码时,经常看到下面这样的写法:

 begin tran
         update statement 1 ...
         update statement 2 ...
         delete statement 3 ...
      commit tran

这样编写的SQL存在很大隐患。请看下面的例子:

create table demo(id int not null)
   go

   begin tran
      insert into demo values (null)
      insert into demo values (2)
   commit tran
   go

执行时会出现一个违反 not null 约束的错误信息,但随后又提示(1 row(s) affected)。 我们执行 select * from demo 后发现 insert into demo values(2) 却执行成功了。 这是什么原因呢? 原来 sql server 在发生 runtime 错误时,默认会 rollback 引起错误的语句,而继续执行后续语句。

如何避免这样的问题呢?有三种方法:

1. 在事务语句最前面加上set xact_abort on

set xact_abort on

   begin tran
      update statement 1 ...
      update statement 2 ...
      delete statement 3 ...
   commit tran
   go

当 xact_abort 选项为 on 时,sql server 在遇到错误时会终止执行并 rollback 整个事务。

2. 在每个单独的DML语句执行后,立即判断执行状态,并做相应处理。

begin tran
      update statement 1 ...

      if @@error <> 0 begin
         rollback tran
         goto labend
      end

      delete statement 2 ...

      if @@error <> 0 begin
         rollback tran
         goto labend
      end

   commit tran
      labend:
   go

3. 在SQL Server 2005中,可利用 try...catch 异常处理机制

begin tran

   begin try
      update statement 1 ...
      delete statement 2 ...
   end try
   begin catch
      if @@trancount > 0
         rollback tran
   end catch

   if @@trancount > 0
      commit tran
   go

下面是个简单的存储过程,演示事务处理过程。

create procedure dbo.pr_tran_inproc
   as
   begin
      set nocount on

      begin tran
         update statement 1 ...

         if @@error <> 0 begin
            rollback tran
            return -1
         end

         delete statement 2 ...

         if @@error <> 0 begin
            rollback tran
            return -1
         end

      commit tran

      return 0
   end
   go

在存储过程中编写正确的事务处理代码

时间: 2024-08-27 17:01:27

在存储过程中编写正确的事务处理代码的相关文章

SQL Server:存储过程中编写事务处理的方法小结

/**8. SQLServer存储过程中编写事务处理的方法小结**/ 原文出处: http://www.jb51.net/article/80636.htm 本文我们介绍了三种不同的方法,举例说明了如何在存储过程事务处理中编写正确的代码. 1. 常见写法: 在编写SQL Server 事务相关的存储过程代码时,经常看到下面这样的写法: begin tran update statement 1 ... update statement 2 ... delete statement 3 ... c

SQL 存储过程中QUOTED_IDENTIFIER on/off

http://huihai.iteye.com/blog/1005144 在存储过程中经常会有 Sql代码   SET QUOTED_IDENTIFIER on SET QUOTED_IDENTIFIER off SET QUOTED_IDENTIFIER on SET QUOTED_IDENTIFIER off 这样的语句,那么SET QUOTED_IDENTIFIER到底是什么意思,有什么用呢,今天下午仔细的看了一下. 如果SET QUOTED_IDENTIFIER on时,在创建一个表时,

存储过程中的事务处理

存储过程中的事务处理 在 SQL Server 中数据库事务处理是个重要的概念,也稍微有些不容易理解,很多 SQL 初学者编写的事务处理代码存往往存在漏洞,本文介绍了三种不同的方法,举例说明了如何在存储过程事务处理中编写正确的代码. 在编写 SQL Server 事务相关的存储过程代码时,经常看到下面这样的写法: begin tran update statement 1 ... update statement 2 ... delete statement 3 ... commit tran

Swift中编写单例的正确方式

Swift中编写单例的正确方式 2015-12-07 10:23 编辑: yunpeng.hu 分类:Swift 来源:CocoaChina翻译活动 14 10647 Objective-CSwift单例 招聘信息: Cocos2d-x 工程师 cocos2dx手游客户端主程 wp开发 iOS开发工程师 iOS软件工程师 iOS研发工程师 iOS讲师 iOS开发工程师 iOS高级开发工程师 iOS 高级软件工程师 iOS高级开发工程师 本文由CocoaChina译者leon(社区ID)翻译自kr

C#和JAVA中编写事务代码

C#  DAL层代码,执行多条增删改,使用事务操作: /// <summary> /// 执行 多条增删改 (非查询语句) /// </summary> /// <param name="strSql"></param> /// <param name="paras"></param> /// <returns></returns> public static int E

Xcode概览:在源码编辑器中编写代码 --【转载】

转自:http://www.cocoachina.com/ios/20141204/10394.html 本章节由CocoaChina翻译组成员星夜暮晨(博客)翻译自Xcode Overview:Write Code in the Source Editor,CocoaChina校对,敬请勘误. 您将大部分开发时间花在了编写.编辑以及调试代码上.Xcode源码编辑器的语法修正.代码补全以及静态代码分析等特性可以帮您快速准确地键入代码.而诸如分拆窗口.快捷键.syntax-aware字体以及文本颜

避免在析构函数中编写代码

上篇文章中,我们介绍了为什么应该彻底避免编写拷贝构造函数和赋值操作符.今天这篇我们讨论下为什么应该避免在析构函数中编写代码.即让析构函数为空. 例如: virtual ~MyClass() { } 我们用空析构函数这个术语表示花括号内没有代码的析构函数. 需要编写析构函数可能有如下几个原因: 在基类中,可能需要声明虚拟析构函数,这样就可以使用一个指向基类的指针指向一个派生类的实例. 在派生类中,并不需要把析构函数声明为虚拟函数,但是为了增强可读性,也可以这样做. 可能需要声明析构函数并不抛出任何

SqlServer和MySQL中存储过程out返回值处理C#代码

1.SqlServer中out处理 C#代码 #region"SqlServer中存储过程处理out返回值" //public void getdata() //{ // string str = " server=192.168.xxxx ;user id=xxx;[email protected]#;database=xxxxx_db;min pool size=4;max pool size=4;packet size=3072"; // SqlConnect

SQL Server 第四堂课,创建存储过程。存储过程是一组编译在单个执行计划中的transact-SQL语句。存储过程相当于C#函数,可以允许模块化程序设计,允许更快执行如果某操作需要大量transct-SQL代码或需要重复执行,将在创建存储过程中对其进行分析和优化。

select *from fruit use shuiguo --存储过程格式 create proc 存储过程名 --输入参数:当调用存储过程时,所需要输入的数据 --输出参数:从存储过程中赋值后带出数据 as --存储过程内容 return 返回值 go exec 返回值=存储过程名 参数一,参数二,....参数N --进销存存储过程 alter proc Jinchuhuo --定义函数名,相当于C#语言里的 public int 函数名 @ids varchar(50), --定义变量,