如何解决这是存储过程中的良好写入事务吗
| 这是我第一次使用交易,我只是想知道我做对了吗。我应该改变一些东西吗? 我插入帖子(wisp)。当插入帖子时,我需要在commentableEntity表中生成ID,然后在wisp表中插入该ID。ALTER PROCEDURE [dbo].[sp_CreateWisp]
@m_UserId uniqueidentifier,@m_WispTypeId int,@m_CreatedOnDate datetime,@m_PrivacyTypeId int,@m_WispText nvarchar(200)
AS
BEGIN TRANSACTION
DECLARE @wispId int
INSERT INTO dbo.tbl_Wisps
(UserId,WispTypeId,CreatedOnDate,PrivacyTypeId,WispText)
VALUES
(@m_UserId,@m_WispTypeId,@m_CreatedOnDate,@m_PrivacyTypeId,@m_WispText)
if @@ERROR <> 0
BEGIN
ROLLBACK
RAISERROR (\'Error in adding new wisp.\',16,1)
RETURN
END
SELECT @wispId = SCOPE_IDENTITY()
INSERT INTO dbo.tbl_CommentableEntity
(ItemId)
VALUES
(@wispId)
if @@ERROR <> 0
BEGIN
ROLLBACK
RAISERROR (\'Error in adding commentable entity.\',1)
RETURN
END
DECLARE @ceid int
select @ceid = SCOPE_IDENTITY()
UPDATE dbo.tbl_Wisps SET CommentableEntityId = @ceid WHERE WispId = @wispId
if @@ERROR <> 0
BEGIN
ROLLBACK
RAISERROR (\'Error in adding wisp commentable entity id.\',1)
RETURN
END
COMMIT
使用基于@gbn答案的try / catch:
ALTER PROCEDURE [dbo].[sp_CreateWisp]
@m_UserId uniqueidentifier,@m_WispText nvarchar(200)
AS
SET XACT_ABORT,NOCOUNT ON
DECLARE @starttrancount int
BEGIN TRY
SELECT @starttrancount = @@TRANCOUNT
IF @starttrancount = 0
BEGIN TRANSACTION
DECLARE @wispId int
INSERT INTO dbo.tbl_Wisps
(UserId,WispText)
VALUES
(@m_UserId,@m_WispText)
SELECT @wispId = SCOPE_IDENTITY()
INSERT INTO dbo.tbl_CommentableEntity
(ItemId)
VALUES
(@wispId)
DECLARE @ceid int
select @ceid = SCOPE_IDENTITY()
UPDATE dbo.tbl_Wisps SET CommentableEntityId = @ceid WHERE WispId = @wispId
IF @starttrancount = 0
COMMIT TRANSACTION
END TRY
BEGIN CATCH
IF XACT_STATE() <> 0 AND @starttrancount = 0
ROLLBACK TRANSACTION
RAISERROR (\'Error in adding new wisp\',1)
END CATCH
GO
解决方法
从SQL Server 2005开始,您将使用TRY / CATCH
回滚进入CATCH块,但否则代码看起来不错(使用SCOPE_IDENTITY()等)。我也会用
SET XACT_ABORT,NOCOUNT ON
这是我的模板:包含TRY CATCH ROLLBACK模式的嵌套存储过程?
编辑:
这允许根据DeveloperX的答案进行嵌套交易
根据Randy的评论,此模板还允许进行更高级别的交易
, 我认为它一直都不好,但是如果您想同时使用多个存储过程,那将是不好的,因为每个存储过程都是独立处理事务的
但是在这种情况下,您应该使用try catch block进行异常处理,并防止在引发异常时保持事务打开
, 我从来没有考虑过将事务放入存储过程中是一个好主意。我认为最好在更高级别启动事务,以便更好地协调多个数据库(例如存储过程)调用并将它们全部视为一个事务。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。