存储过程中的事务处理

存储过程中的事务处理

在 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

存储过程中的事务处理,布布扣,bubuko.com

时间: 2024-10-20 04:34:36

存储过程中的事务处理的相关文章

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

Oracle存储过程中异常Exception的捕捉和处理

Oracle存储过程中异常的捕捉和处理 CREATE OR REPLACE Procedure Proc_error_process ( v_IN in Varchar2, v_OUT Out Varchar2) AUTHID CURRENT_USER AS --声明异常 some_kinds_of_err EXCEPTION; -- Exception to indicate an error condition v_ErrorCode NUMBER; -- Variable to hold

ASP.NET开发过程中的事务处理

今天重新看了一遍<asp.net高级程序设计第四版>的第七章,关于asp.net的事务处理这一块,之前看的时候由于工作中也没有用到它所以没怎么在意,不过真是应了那句话:温故而知新呀. 今天的内容不是很多,代码演示也不多,所以可以早早写完休息. 事务:事务可以理解为一种必须同时完成或全部失败的操作.书中的经典例子:账户转账,A账户与B账户之前必须A-100同时B+100,这个操作必须同时成功,只要有个失败两个步骤都需要回滚,这样的一个完整过程就可以称为一个[事务]. 整个小节讲解事务处理可以归纳

在oracle存储过程中创建临时表

在oracle的存储过程中,不能直接使用DDL语句,比如create.alter.drop.truncate等. 那如果我们想在存储过程中建立一张临时表就只能使用动态sql语句了: create or replace procedure pro as str_sql varchar2(100); begin -- 创建临时表 str_sql := 'create global temporary table temp_table ( col1 varchar2(10), col2 number

sqlserver 存储过程中使用临时表到底会不会导致重编译

曾经在网络上看到过,SqlServer的存储过程中使用临时表,会导致执行计划无法重用, 运行时候会导致重编译的这么一个说法,自己私底下去做测试的时候,根据profile的跟踪结果, 如果不是统计信息变更导致导致的重编译,单单是使用临时表,并不会导致重编译, 但是对于一些特殊的情况,又确实会出现重编译的, 为了弄清楚这个问题,查阅了大量的资料,才把这个问题弄清楚,这里特意记录下来,希望武断地认为存储过程中使用了临时表就会导致重编译的这个观点得到纠正. 首先进行下面的测试,我们知道,导致临时表重编译

SQL Server存储过程中使用事务

今天修改之前一个同事写的代码,发现方法中直接执行了两个sql语句,一个是删除用户,一个是删除该用户的权限.由于数据库数据比较多,导致有时候这个两个sql不能都执行成功,数据库出现了脏数据. 鉴于这个原因,我把两个sql放到了一个存储过程中执行,在存储过程中添加事务,使其要么都执行,要么都不执行. 代码框架如下: 1 CREATE PROCEDURE pro_TrancDemo @backvalue INT OUTPUT 2 AS 3 BEGIN 4 SET NOCOUNT ON; 5 6 BEG

Sql Server 存储过程中查询数据无法使用 Union(All)

原文:Sql Server 存储过程中查询数据无法使用 Union(All) 微软Sql Server数据库中,书写存储过程时,关于查询数据,无法使用Union(All)关联多个查询. 1.先看一段正常的SQL语句,使用了Union(All)查询: SELECT ci.CustId --客户编号 , ci.CustNam --客户名称 , ci.ContactBy --联系人 , ci.Conacts --联系电话 , ci.Addr -- 联系地址 , ci.Notes --备注信息 , ai

Sql server中根据存储过程中的部分信息查找存储过程名称的方法【视图和Function】

1.查询的语句: select a.id,b.name,a.*,b.* from syscomments a join sysobjects b on a.id=b.id where b.xtype='P' and a.text like '%usp_cm%' b.xtype='P'指定在什么类型的范围进行搜索 '%usp_cm%'就是你能记得的存储过程中的内容. 2.查找类型: select distinct xtype from sysobjects 找到数据库中所有的对象类型 P是存储过程