日期:2014-05-18  浏览次数:20477 次

存储过程事务为什么不回滚?
create proc usp_ChangeHander  
 @UserGUID VARCHAR(40),
 @EventGUID VARCHAR(40),
 @WorkL money,
 @Ru VARCHAR(40) --更改的人
AS  
  begin
  DECLARE @strUserName VARCHAR(10)  
DECLARE @strDepartment VARCHAR(40)  
DECLARE @strGW VARCHAR(20)
DECLARE @date VARCHAR(24)
DECLARE @count int

BEGIN
SELECT @strUserName =UserName, @strDepartment=CONVERT(varchar(40),DepartmentGUID),@strGW =JobTitle FROM myuser WHERE USERGUID = @UserGUID
END
BEGIN TRANSACTION tr
SET @date = getdate()

EXEC (N'UPDATE Itsm_EventInfo SET NowHandlerGUID ='''+@UserGUID+''' where EventGUID = '''+@EventGUID+''';
INSERT INTO Itsm_WorkLoad VALUES (newid(),'''+ @EventGUID +''','''+@Ru+''','''+@strDepartment+''','''+@WorkL+''','''+@strGW+''',''2'',''2'');
INSERT INTO Itsm_ProcessReport VALUES (newid(),'''+ @EventGUID +''','''+@date+''',''更改处理人'','''+@Ru+''','''+@strUserName+''','''','''')
')
IF @@ERROR<>0
begin
ROLLBACK TRANSACTION tr
SELECT 'FAILED'
end
ELSE
begin
COMMIT TRANSACTION tr
SELECT 'SUCCESS'
end
  end
GO

我故意把其中一张表的字段位数改小,运行存储过程
结果 
(1 行受影响)
消息 8152,级别 16,状态 14,第 2 行
将截断字符串或二进制数据。
语句已终止。

(1 行受影响)

(1 行受影响)

然后去查两外的表 数据居然都插进去了,也就是没回滚。。。帮我看看呢。。




------解决方案--------------------
试试begin try
------解决方案--------------------
你断定执行语句有错误吗?
------解决方案--------------------
如果前一个 Transact-SQL 语句执行没有错误,则返回 0。

如果前一个语句遇到错误,则返回错误号。如果错误是 sys.messages 目录视图中的错误之一,则 @@ERROR 将包含 sys.messages.message_id 列中表示该错误的值。可以在 sys.messages 中查看与 @@ERROR 错误号相关的文本信息。

由于 @@ERROR 在每一条语句执行后被清除并且重置,因此应在语句验证后立即查看它,或将其保存到一个局部变量中以备以后查看。

使用 TRY...CATCH 构造来处理错误。TRY...CATCH 构造也支持其他返回的错误信息多于 @@ERROR 的系统函数(ERROR_LINE、ERROR_MESSAGE、ERROR_PROCEDURE、ERROR_SEVERITY 和 ERROR_STATE)。TRY...CATCH 也支持 ERROR_NUMBER 函数,但不限制该函数在语句产生错误后立即在语句中返回错误号。

------解决方案--------------------
TRY...CATCH 看看
------解决方案--------------------
try this, 
SQL code

create proc usp_ChangeHander   
 @UserGUID VARCHAR(40),
 @EventGUID VARCHAR(40),
 @WorkL money,
 @Ru VARCHAR(40) --更改的人
AS   
begin
DECLARE @strUserName VARCHAR(10)   
DECLARE @strDepartment VARCHAR(40)   
DECLARE @strGW VARCHAR(20)
DECLARE @date VARCHAR(24)
DECLARE @count int

BEGIN
SELECT @strUserName =UserName, @strDepartment=CONVERT(varchar(40),DepartmentGUID),@strGW =JobTitle FROM myuser WHERE USERGUID = @UserGUID
end
set xact_abort on
BEGIN TRANSACTION tr
SET @date = getdate()

EXEC (N'UPDATE Itsm_EventInfo SET NowHandlerGUID ='''+@UserGUID+''' where EventGUID = '''+@EventGUID+''';
INSERT INTO Itsm_WorkLoad VALUES (newid(),'''+ @EventGUID +''','''+@Ru+''','''+@strDepartment+''','''+@WorkL+''','''+@strGW+''',''2'',''2'');
INSERT INTO Itsm_ProcessReport VALUES (newid(),'''+ @EventGUID +''','''+@date+''',''更改处理人'','''+@Ru+''','''+@strUserName+''','''','''')
')
IF @@ERROR<>0
begin
ROLLBACK TRANSACTION tr
SELECT 'FAILED'
end
ELSE
begin
COMMIT TRANSACTION tr
SELECT 'SUCCESS'
end
  end
GO

------解决方案--------------------
@@error 只记录它之前的最后一个值,你这里有3个语句,每个语句都需要单独做@@error判断