存储过程中,也要加入commit吗?

好记忆不如烂笔头abc 2007-07-10 04:50:32
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.如果要应该在哪些地方加合适?

谢谢!
...全文
1760 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
明白了,非常感谢各位大侠的指点。
再次感谢!
OracleRoob 2007-07-10
  • 打赏
  • 举报
回复
楼上举的银行转账是一个非常典型的例子
如果你多个SQL需要:“要么全作,要么不做”这样的需求,就应该加事务。
hellowork 2007-07-10
  • 打赏
  • 举报
回复
请参考上面银行转账的例子.
到底需不需要显式启动事务,要看楼主的需求.如果要求批处理中执行的若干个插入或更新操作必须保证要么一次成功,否则全部失败,那么就应该为这些操作启用一个事务.
OracleRoob 2007-07-10
  • 打赏
  • 举报
回复
begin tran 和commit tran是成对使用的。

如果你的SP中没有begin tran,就不能写commit tran

对于单个SQL语句而言,它本身是原子性的,不会出现一个Update语句,需要更新100条,而中间出错了,只更新了50条。

所以,单个SQL语句,踏本身就是一个隐性的事务,没有必要加begin tran和commit tran。

但是一旦有多个SQL语句时,如果你多个SQL需要:“要么全作,要么不做”这样的需求,就应该加事务。
  • 打赏
  • 举报
回复
1.我的sp中没有begin tran
2.sp中有updata,insert,select
3.有说:自动提交事务:这是 SQL Server 的默认模式。每个单独的 Transact-SQL 语句都在其完成后提交。不必指定任何语句控制事务。--每个sp应该算是单独的Transact-SQL 语句吧?

综上,不加commit也是可以的吧?

hellowork 2007-07-10
  • 打赏
  • 举报
回复
象楼上说的那样,如果楼主的需要与银行转账类似,就应该将修改方到事务中,例如转账:
1.将账户的金额减掉转账金额;
2.将目的账户的钱加上转账金额
这两步是连贯的,如果不将这两步方到同一个事务中,那么当完成第一步而进行第二步时若出错,后果就是第一步的钱已经被划掉,而目的账户却没得到钱,钱就这样蒸发了.
OracleRoob 2007-07-10
  • 打赏
  • 举报
回复
如果你的SP中不是一个操作性的SQL,而是包含多个,就应该加事务。
OracleRoob 2007-07-10
  • 打赏
  • 举报
回复
begin tran 和commit tran是成对使用的。

如果你多个SQL需要:“要么全作,要么不做”这样的需求,就应该加事务。

  • 打赏
  • 举报
回复
chuifengde(树上的鸟儿) ( ) 信誉:100 Blog 加为好友 2007-07-10 16:55:23 得分: 0


commit和begin是成对的,另:你就一个原子语句,没必要加

==============================
还有大侠赞同chuifengde(树上的鸟儿)的观点吗?
  • 打赏
  • 举报
回复
有书上说:
在 Microsoft® SQL Server™ 中,可以按显式自动提交或隐性模式启动事务。

1) 显式事务:通过发出 BEGIN TRANSACTION 语句显式启动事务。

2) 自动提交事务:这是 SQL Server 的默认模式。每个单独的 Transact-SQL 语句都在其完成后提交。不必指定任何语句控制事务。

3) 隐性事务:通过 API 函数或 Transact-SQL SET IMPLICIT_TRANSACTIONS ON 语句,将隐性事务模式设置为打开。下一个语句自动启动一个新事务。当该事务完成时,再下一个 Transact-SQL 语句又将启动一个新事务。
======================
说默认就是自动提交事务了,那意味着我的那个存储过程可以不用加commit吧?
OracleRoob 2007-07-10
  • 打赏
  • 举报
回复
1.只要在存储过程的begin和end 前后加上begin tran
和commit tran就可以了吗?
-----------------------------
根据具体情况而定,多个SQL语句放在一个同一个事务中。


2.为什么还要加个return 0呢?
-----------------------------
return 0
表示存储过程执行成功了,如果SP执行失败,系统返回的值一定不是0
  • 打赏
  • 举报
回复
to hellowork(一两清风)
不加就不能确保吗?sqlserver本身默认是在什么情况下会commit的?
hellowork 2007-07-10
  • 打赏
  • 举报
回复
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
  • 打赏
  • 举报
回复
是不是这么理解,如果不加begin tran和commit tran的话,就不会被认为是一个事务,那么可能就出现数据混乱的状态?

to wangtiecheng(不知不为过,不学就是错!)

1.只要在存储过程的begin和end 前后加上begin tran
和commit tran就可以了吗?
2.为什么还要加个return 0呢?
多谢!
jacket008 2007-07-10
  • 打赏
  • 举报
回复
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
xmlquit 2007-07-10
  • 打赏
  • 举报
回复
根據自己的需要來定義事務的大小。然後再每個事務commit,rollback
OracleRoob 2007-07-10
  • 打赏
  • 举报
回复
CREATE procedure xxx
@xxx nvarchar(15)
as

set nocount on


--当 SET XACT_ABORT 为 ON 时,如果 Transact-SQL 语句产生运行时错误,整个事务将终止并回滚。为
--OFF 时,只回滚产生错误的 Transact-SQL 语句,而事务将继续进行处理。
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
hellowork 2007-07-10
  • 打赏
  • 举报
回复
最好加事务,以确保要么全成功,要么全失败,避免一半成功一半失败的情况.
把更新和插入或删除操作放到一个事务中就可以了.
chuifengde 2007-07-10
  • 打赏
  • 举报
回复
commit和begin是成对的,另:你就一个原子语句,没必要加
OracleRoob 2007-07-10
  • 打赏
  • 举报
回复
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

34,575

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧