存储过程中,也要加入commit吗?
CREATE procedure xxx
@xxx nvarchar(15)
as
set nocount on
update xxx set xxx=1 where xxx=@xxx
begin
if exists(select top 1 id from xxx where xxx=@xxx)
update xxx
set
xxx1=getdate(),
xxx=xxx
where
xxx=@xxx
else
insert into xxx(xxx)
values(@xxx)
end
GO
请教大侠们:
1.有必要加commit吗?如果不加,会出什么问题?
2.如果要应该在哪些地方加合适?
谢谢!
[解决办法]
CREATE procedure xxx
@xxx nvarchar(15)
as
set nocount on
set xact_abort on
begin tran
update xxx set xxx=1 where xxx=@xxx
begin
if exists(select top 1 id from xxx where xxx=@xxx)
update xxx
set
xxx1=getdate(),
xxx=xxx
where
xxx=@xxx
else
insert into xxx(xxx)
values(@xxx)
end
commit tran
return 0
go
[解决办法]
commit和begin是成对的,另:你就一个原子语句,没必要加
[解决办法]
最好加事务,以确保要么全成功,要么全失败,避免一半成功一半失败的情况.
把更新和插入或删除操作放到一个事务中就可以了.
[解决办法]
根自己的需要定事的大小。然後再每事commit,rollback
[解决办法]
CREATE procedure xxx
@xxx nvarchar(15)
as
set nocount on
begin tran
update xxx set xxx=1 where xxx=@xxx
if @@error <> 0 goto error
if exists(select top 1 id from xxx where xxx=@xxx)
update xxx
set
xxx1=getdate(),
xxx=xxx
where
xxx=@xxx
else
insert into xxx(xxx)
values(@xxx)
if @@error <> 0 goto error
commit
return
error:
rollback
[解决办法]
CREATE procedure xxx
@xxx nvarchar(15)
as
set nocount on
BEGIN TRANSACTION /*开始事务*/
update xxx set xxx=1 where xxx=@xxx
if @@error <> 0
begin
raiserror( '抱歉,更新时发生错误,更新失败! '16,1)
ROLLBACK /*回滚,取消修改*/
return
end
if exists(select 1 from xxx where xxx=@xxx)
begin
update xxx set xxx1=getdate(), xxx=xxx
where xxx=@xxx
if @@error <> 0
begin
raiserror( '抱歉,更新时发生错误,更新失败! '16,1)
ROLLBACK /*回滚,取消修改*/
return
end
end
else
begin
insert into xxx(xxx) values(@xxx)
if @@error <> 0
begin
raiserror( '抱歉,插入时发生错误,更新失败! '16,1)
ROLLBACK /*回滚,取消修改*/
return
end
end
COMMIT TRANSACTION /*提交事务,保持修改*/
GO
[解决办法]
1.只要在存储过程的begin和end 前后加上begin tran
和commit tran就可以了吗?
-----------------------------
根据具体情况而定,多个SQL语句放在一个同一个事务中。
2.为什么还要加个return 0呢?
-----------------------------
return 0
表示存储过程执行成功了,如果SP执行失败,系统返回的值一定不是0
[解决办法]
象楼上说的那样,如果楼主的需要与银行转账类似,就应该将修改方到事务中,例如转账:
1.将账户的金额减掉转账金额;
2.将目的账户的钱加上转账金额
这两步是连贯的,如果不将这两步方到同一个事务中,那么当完成第一步而进行第二步时若出错,后果就是第一步的钱已经被划掉,而目的账户却没得到钱,钱就这样蒸发了.
[解决办法]
begin tran 和commit tran是成对使用的。
如果你的SP中没有begin tran,就不能写commit tran
对于单个SQL语句而言,它本身是原子性的,不会出现一个Update语句,需要更新100条,而中间出错了,只更新了50条。
所以,单个SQL语句,踏本身就是一个隐性的事务,没有必要加begin tran和commit tran。
但是一旦有多个SQL语句时,如果你多个SQL需要:“要么全作,要么不做”这样的需求,就应该加事务。
[解决办法]
请参考上面银行转账的例子.
到底需不需要显式启动事务,要看楼主的需求.如果要求批处理中执行的若干个插入或更新操作必须保证要么一次成功,否则全部失败,那么就应该为这些操作启用一个事务.