两个存储过程之间调用,怎样保证在同一个事物中完成?

up369 2013-08-19 03:55:59
有两个存储过程p_1,p_2。怎样能保证在p_1调用p_2时如果哪个过程出现错误时,事物全部回滚。也就是说要么全部提交要么全部回滚?最好给个例子,谢谢!
...全文
373 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
唐诗三百首 2013-08-21
  • 打赏
  • 举报
回复
SQL2000的写法..

set xact_abort on
begin tran
 exec p_1
 exec p_2
commit tran
lzw_0736 2013-08-21
  • 打赏
  • 举报
回复

--完整測試示例

--1)建立測試表
CREATE TABLE tb1 (id INT,field1 TINYINT)
INSERT tb1
SELECT 1,1
UNION ALL
SELECT 2,2

CREATE TABLE tb2 (id INT,field2 TINYINT)
INSERT tb2
SELECT 1,1
UNION ALL
SELECT 2,2
GO

--2)建立測試存儲過程
CREATE PROC [dbo].[up_test1]
AS
begin
	declare @err int
    UPDATE tb1 SET field1 = 11
    WHERE id = 1
    SET @err=@@ERROR
    IF @err>0
		BEGIN
			SELECT @err
			RETURN
		END
    EXEC up_test2
	SELECT @@ERROR
end
GO

CREATE PROC [dbo].[up_test2]
AS
begin
    UPDATE tb2 SET field2 = 322
    WHERE id = 2
end
GO

--3)執行事務
DECLARE @t TABLE (err INT)
BEGIN TRAN
INSERT @t exec up_test1
IF (select err FROM @t)>0
	begin
		ROLLBACK TRAN
		PRINT '失敗'
	end
ELSE
	begin
		COMMIT TRAN
		PRINT '成功'
	end
Shawn 2013-08-21
  • 打赏
  • 举报
回复
引用 12 楼 up369 的回复:
又回到原点了,麻烦给个例子吧
--#2.2000的话,用SER XACT_ABORT ON环境选项,就可以了 SET XACT_ABORT ON BEGIN TRAN EXEC up_test1 COMMIT TRAN --参考: http://bbs.csdn.net/topics/390133361
phprun 2013-08-21
  • 打赏
  • 举报
回复
被调用的存储过程中,也可以写个事务,并把事务的返回值,传回到调用的存储过程中来,然后,这个调用的存储过程中也要写事务进行判断和处理自己这一块出现的错误及 上面那个调用回来的存储过程出现的错误值。
up369 2013-08-19
  • 打赏
  • 举报
回复
又回到原点了,麻烦给个例子吧
發糞塗牆 2013-08-19
  • 打赏
  • 举报
回复
2000没有,你可以用if来判断
up369 2013-08-19
  • 打赏
  • 举报
回复
sql 2000是不是没有 BEGIN TRY END TRY BEGIN CATCH END CATCH 功能啊?
Shawn 2013-08-19
  • 打赏
  • 举报
回复
引用 6 楼 up369 的回复:
to:wwwwgou 用不用判断up_test2的返回值有没有错误发生?
如#7楼所说。不用。 这种写法的缺点,就是可能导致大事务的产生,锁的时间会加长。 优点就是:方便,整体作为一个事务。
--小F-- 2013-08-19
  • 打赏
  • 举报
回复
如果你要捕捉错误信息的话 在CATCH子句里面去捕捉
--小F-- 2013-08-19
  • 打赏
  • 举报
回复
引用 6 楼 up369 的回复:
to:wwwwgou 用不用判断up_test2的返回值有没有错误发生?
如果已经显式声明事务的话 可以不用判断了
up369 2013-08-19
  • 打赏
  • 举报
回复
to:wwwwgou 用不用判断up_test2的返回值有没有错误发生?
Shawn 2013-08-19
  • 打赏
  • 举报
回复
CREATE PROC up_test1
AS
	UPDATE tb1 SET field1 = 1
	WHERE id = 1
	EXEC up_test2
GO

CREATE PROC up_test2
AS
	UPDATE tb2 SET field2 = 2
	WHERE id = 2
GO

--显示声明事务,无论有多少代码,都放在begin tran和commit tran之间就好了.
--切记,不要嵌套事务。如果嵌套事务,异常时执行的第一个ROLLBACK语句会回滚所有的事务
--#1.在最外层用TRY...CATCH...
BEGIN TRY
	BEGIN TRAN
	EXEC up_test1
	COMMIT TRAN  
END TRY
BEGIN CATCH
	ROLLBACK
END CATCH

--#2.用SER XACT_ABORT ON环境选项
SET XACT_ABORT ON
BEGIN TRAN
	EXEC up_test1
COMMIT TRAN
--小F-- 2013-08-19
  • 打赏
  • 举报
回复
引用 3 楼 up369 的回复:
我是两个存储过程,怎么写在一个事物里呢?
你用一楼的吧 分别判断吧。
up369 2013-08-19
  • 打赏
  • 举报
回复
我是两个存储过程,怎么写在一个事物里呢?
--小F-- 2013-08-19
  • 打赏
  • 举报
回复
事务都是要么提交 要么回滚 有什么问题? 你直接写在一个事务里面就可以了 实在是害怕的话 加上SER XACT_ABORT ON
發糞塗牆 2013-08-19
  • 打赏
  • 举报
回复
begin tran t1 exec p_1 if xxx/try catch begin tran t2 exec p_2 if xxx/try catach 分别判断,成功就继续,不成功就分别回滚

34,593

社区成员

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

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