当前位置: 代码迷 >> Sql Server >> 两个存储过程其间调用,怎样保证在同一个事物中完成
  详细解决方案

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

热度:61   发布时间:2016-04-24 20:22:16.0
两个存储过程之间调用,怎样保证在同一个事物中完成?
有两个存储过程p_1,p_2。怎样能保证在p_1调用p_2时如果哪个过程出现错误时,事物全部回滚。也就是说要么全部提交要么全部回滚?最好给个例子,谢谢!

------解决方案--------------------
begin tran t1
  exec p_1
  if xxx/try catch
begin tran t2
   exec p_2
   if xxx/try catach 
分别判断,成功就继续,不成功就分别回滚
------解决方案--------------------
事务都是要么提交 要么回滚 有什么问题?

你直接写在一个事务里面就可以了 实在是害怕的话 加上SER XACT_ABORT ON
------解决方案--------------------
引用:
我是两个存储过程,怎么写在一个事物里呢?

你用一楼的吧 分别判断吧。
------解决方案--------------------
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

------解决方案--------------------
引用:
to:wwwwgou 
用不用判断up_test2的返回值有没有错误发生?

如果已经显式声明事务的话 可以不用判断了 
------解决方案--------------------
如果你要捕捉错误信息的话 在CATCH子句里面去捕捉 
------解决方案--------------------
引用:
to:wwwwgou 
用不用判断up_test2的返回值有没有错误发生?

如#7楼所说。不用。
这种写法的缺点,就是可能导致大事务的产生,锁的时间会加长。
优点就是:方便,整体作为一个事务。
------解决方案--------------------
2000没有,你可以用if来判断
------解决方案--------------------
被调用的存储过程中,也可以写个事务,并把事务的返回值,传回到调用的存储过程中来,然后,这个调用的存储过程中也要写事务进行判断和处理自己这一块出现的错误及 上面那个调用回来的存储过程出现的错误值。


------解决方案--------------------
引用:
又回到原点了,麻烦给个例子吧

--#2.2000的话,用SER XACT_ABORT ON环境选项,就可以了
SET XACT_ABORT ON
BEGIN TRAN
    EXEC up_test1
COMMIT TRAN
--参考:
http://bbs.csdn.net/topics/390133361
------解决方案--------------------

--完整測試示例

--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

------解决方案--------------------
SQL2000的写法..

set xact_abort on
begin tran
 exec p_1
 exec p_2
commit tran
  相关解决方案