Sql server 这是存储过程中的良好写入事务吗
这是我第一次使用事务,我只是想知道我是否做对了。我应该换点什么吗? 我插入后(wisp)。当插入post时,我需要在commentableEntity表中生成ID,并在wisp表中插入该IDSql server 这是存储过程中的良好写入事务吗,sql-server,tsql,stored-procedures,transactions,scope,Sql Server,Tsql,Stored Procedures,Transactions,Scope,这是我第一次使用事务,我只是想知道我是否做对了。我应该换点什么吗? 我插入后(wisp)。当插入post时,我需要在commentableEntity表中生成ID,并在wisp表中插入该ID ALTER PROCEDURE [dbo].[sp_CreateWisp] @m_UserId uniqueidentifier, @m_WispTypeId int, @m_CreatedOnDate datetime, @m_PrivacyTypeId int, @m_WispText nvarchar
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.', 16, 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.', 16, 1)
RETURN
END
COMMIT
ALTER过程[dbo]。[sp_CreateWisp]
@m_用户标识唯一标识符,
@m_WispTypeId int,
@m_CreatedOnDate日期时间,
@m_PrivacyTypeId int,
@m_WispText nvarchar(200)
作为
开始交易
声明@wispId int
插入到dbo.tbl_束中
(用户ID、WispTypeId、CreatedOnDate、PrivacyTypeId、WispText)
价值观
(@m_UserId、@m_WispTypeId、@m_CreatedOnDate、@m_PrivacyTypeId、@m_WispText)
如果@错误0
开始
回降
RAISERROR('添加新wisp时出错',16,1)
返回
结束
选择@wispId=SCOPE\u IDENTITY()
插入dbo.tbl_CommentableEntity
(项目ID)
价值观
(@wispId)
如果@错误0
开始
回降
RAISERROR('添加可注释实体时出错',16,1)
返回
结束
声明@ceid int
选择@ceid=SCOPE\u IDENTITY()
更新dbo.tbl_Wisps SET CommentableEntityId=@ceid,其中WispId=@WispId
如果@错误0
开始
回降
RAISERROR('添加wisp可注释实体id时出错',16,1)
返回
结束
犯罪
基于@gbn-answer使用try/catch:
ALTER PROCEDURE [dbo].[sp_CreateWisp]
@m_UserId uniqueidentifier,
@m_WispTypeId int,
@m_CreatedOnDate datetime,
@m_PrivacyTypeId int,
@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,WispTypeId,CreatedOnDate,PrivacyTypeId,WispText)
VALUES
(@m_UserId,@m_WispTypeId,@m_CreatedOnDate,@m_PrivacyTypeId,@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', 16, 1)
END CATCH
GO
ALTER过程[dbo]。[sp_CreateWisp]
@m_用户标识唯一标识符,
@m_WispTypeId int,
@m_CreatedOnDate日期时间,
@m_PrivacyTypeId int,
@m_WispText nvarchar(200)
作为
设置XACT_中止,不计数为ON
声明@starttrancount int
开始尝试
选择@starttrancount=@@TRANCOUNT
如果@starttrancount=0
开始交易
声明@wispId int
插入到dbo.tbl_束中
(用户ID、WispTypeId、CreatedOnDate、PrivacyTypeId、WispText)
价值观
(@m_UserId、@m_WispTypeId、@m_CreatedOnDate、@m_PrivacyTypeId、@m_WispText)
选择@wispId=SCOPE\u IDENTITY()
插入dbo.tbl_CommentableEntity
(项目ID)
价值观
(@wispId)
声明@ceid int
选择@ceid=SCOPE\u IDENTITY()
更新dbo.tbl_Wisps SET CommentableEntityId=@ceid,其中WispId=@WispId
如果@starttrancount=0
提交事务
结束尝试
开始捕捉
如果XACT_STATE()为0且@starttrancount=0
回滚事务
RAISERROR('添加新wisp时出错',16,1)
端接
去
自SQL Server 2005以来,您将使用TRY/CATCH+
回滚进入CATCH块,但在其他方面代码看起来不错(使用SCOPE_IDENTITY()等)。我也会使用SET XACT\u ABORT,NOCOUNT ON
这是我的模板:
编辑:
- 这允许按照DeveloperX的回答进行嵌套事务
- 根据Randy的评论,该模板还允许进行更高级别的交易
但在这种情况下,您应该使用try-catch块来处理异常,并防止在异常引发时打开事务。我从未认为将事务放入存储过程是一个好主意。我认为最好从更高的级别开始事务,这样可以更好地协调多个数据库(例如存储过程)调用,并将它们视为单个事务。请参见我答案中的链接:易于嵌套是的,我的答案是关于将事务放入存储过程,在这种情况下,您的答案是正确的,那么您需要MSDTC的参与。在可能的情况下,写入的每个数据库调用都应该是原子的吗?请查看我的答案,了解如何处理它的模板。您好,我根据您的模板添加了新代码。请确认这很好,以便我可以结束此问题;)