M2X*_*M2X 6 sql-server performance transactions
现在我和一位同事正在争论非重要的BEGIN TRAN ...... COMMIT TRAN块的影响.我已经为简单的插入更新删除操作写了大约140个存储过程,因为我们以后可能需要在它们中做一些额外的操作,我已经包含了可能是必要的BEGIN TRAN和COMMIT TRAN块,如下所示:
CREATE PROCEDURE [Users].[Login_Insert]
@Username nvarchar (50) OUTPUT,
@Password char (40),
@FullName nvarchar (150),
@LoginTypeId int
AS
SET NOCOUNT ON;
BEGIN TRY
BEGIN TRAN
INSERT [Users].[Login]
(
[Username],
[Password],
[FullName],
[LoginTypeId]
)
VALUES
(
@Username,
@Password,
@FullName,
@LoginTypeId
)
COMMIT TRAN
RETURN 1
END TRY
BEGIN CATCH
ROLLBACK TRAN
RETURN -1
END CATCH
GO
Run Code Online (Sandbox Code Playgroud)
现在许多这些交易可能永远不必要.这些无关的块是否会以明显的方式影响性能?提前致谢.
不足以引起注意.
也就是说,每个TXN将在BEGIN TRAN和INSERT之间打开额外的OhNoSecond.如果有人能测量它,我会留下深刻的印象.
但是,如果你做BEGIN TRAN然后提示用户输入,你的腿需要打破......
好主意:我这样做所以我的所有写入过程100%一致,具有相同的错误处理,可以嵌套等
编辑:在Remus的回答之后,我看到我没有链接到我的嵌套TXN模板:包含TRY CATCH ROLLBACK模式的嵌套存储过程?这与Remus的不同之处在于它总是回滚并且没有SAVEPOINT
编辑,一个快速而肮脏的测试显示它在交易时间的2/3左右更快
SET NOCOUNT ON
SET STATISTICS IO OFF
DECLARE @date DATETIME2
DECLARE @noTran INT
DECLARE @withTran INT
SET @noTran = 0
SET @withTran = 0
DECLARE @t TABLE (ColA INT)
INSERT @t VALUES (1)
DECLARE
@count INT,
@value INT
SET @count = 1
WHILE @count < 100
BEGIN
SET @date = GETDATE()
UPDATE smalltable SET smalltablename = CASE smalltablename WHEN 'test1' THEN 'test' ELSE 'test2' END WHERE smalltableid = 1
SET @noTran = @noTran + DATEDIFF(MICROSECOND, @date, GETDATE())
SET @date = GETDATE()
BEGIN TRAN
UPDATE smalltable SET smalltablename = CASE smalltablename WHEN 'test1' THEN 'test' ELSE 'test2' END WHERE smalltableid = 1
COMMIT TRAN
SET @withTran = @withTran + DATEDIFF(MICROSECOND, @date, GETDATE())
SET @count = @count + 1
END
SELECT
@noTran / 1000000. AS Seconds_NoTransaction,
@withTran / 1000000. AS Seconds_WithTransaction
Seconds_NoTransaction Seconds_WithTransaction
2.63200000 2.70400000
2.16700000 2.12300000
Run Code Online (Sandbox Code Playgroud)
颠倒更新顺序会保持相同的行为
在您发布的代码中,没有可衡量的影响,但事务确实会影响性能,它们可以显着提高由于日志刷新提交分组而导致的性能,或者由于错误管理的争用问题而显着降低性能.但最重要的是,当正确性需要交易时,你不能跳过它们.话虽这么说,你的模板实际上相对于事务和try-catch块非常糟糕.catch块中的transcation必须对XACT_STATE返回值(-1,0,1)进行三态逻辑检查,并正确处理注定的事务.有关示例,请参阅异常处理和嵌套事务.
此外,您永远不应该将try-catch错误处理与返回代码错误处理混合在一起.选择一个并坚持下去,最好是试一试.换句话说,您的存储过程应该是RAISE,而不是返回-1.将异常与错误代码混合使您的代码成为维护和正确调用的噩梦.