在SQL Server
中,事务可以在客户端或服务器代码中执行。数据库专家曾告诉我,由于锁定问题,应该避免客户端事务。现在,几年后,我想知道这是否仍然适用。
当然,有些情况下客户端事务是必要的,但我们假设可以使用客户端或服务器端事务来解决特定问题。
在性能方面,哪两种技术最好?为什么?
C#(客户端):
using (var transaction = new TransactionScope())
{
// Insert data into database.
transaction.Complete();
}
T-SQL(服务器):
CREATE PROCEDURE [dbo].[my_proc]
AS
BEGIN
SET NOCOUNT ON
DECLARE @TransactionCount [int]
BEGIN TRY
SET @TransactionCount = @@TRANCOUNT
IF @TransactionCount = 0
BEGIN TRANSACTION
-- Insert data
IF @TransactionCount = 0
COMMIT TRANSACTION
END TRY
BEGIN CATCH
IF XACT_STATE() <> 0 AND @TransactionCount = 0
ROLLBACK TRANSACTION
; THROW
END CATCH
END
GO
答案 0 :(得分:2)
我是客户端交易的大力倡导者,只要他们正确完成。
当您执行客户端交易时,您所做的只是打开连接并发送“开始转移”。从这里开始,当您围绕不同的类传递事务对象并执行更新时,您只是使用该打开的连接。出于这个原因,我并不完全同意Gregg的回答,因为您使用开放式连接与开放式交易,因此服务器始终会知道&#39;。
假设它在Try / Finally中正确包围以关闭它,并且还使用&#39;阻止它们非常具体。成功使用它们10年后,我从未遇到锁定问题。
我通常使用一个包含多个子类的框架...例如,想一个&#39;客户&#39;对象,里面有一组电话号码和地址,每个对象都有自己的更新例程。
如果我要对父进行更新,那么使用服务器端事务回滚更改将非常困难,因为更新都被整齐地排序到每个表/实体的自己的更新sproc中。
传递客户端事务并调用此事务中的存储过程,我可以选择在抛出任何异常时干净地回滚,并在知道更新完成后提交。
当您正确使用交易时,客户端交易是大人物的礼物。
答案 1 :(得分:1)
服务器端事务更有效。这样想吧。如果启动事务客户端,则服务器必须知道正在进行事务才能提交或回滚。这也导致客户端应用程序和数据库服务器之间的更多通信。