有两个存储过程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
------解决方案--------------------
如果已经显式声明事务的话 可以不用判断了
------解决方案--------------------
如果你要捕捉错误信息的话 在CATCH子句里面去捕捉
------解决方案--------------------
如#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