COM+SQL Server 2000DBAWindows 2003ADO.NETArchitectWindows XPSQL Server 2005IntermediateDevVisual StudioSQL ServerSQLWindows.NETASP.NETC#
.NET 1.1 中的 TransactionScope






4.57/5 (7投票s)
2005 年 6 月 1 日
1分钟阅读

100958
在 .NET 1.1 中模拟 .NET 2.0 中即将推出的 TransactionScope 功能。
现在:使用 ServicedComponent 实现声明式数据库事务
自 Windows NT 4.0 时代起,使用 Microsoft SQL Server 的开发人员就享受到了声明式事务处理。在 .NET Framework 中,这意味着通常我们需要从 ServicedComponent
类继承,将 TransactionAttribute
应用到它,并使用 SetAbort
/SetComplete
方法来通知框架我们的数据库操作是否成功或失败。框架负责处理剩下的事情。
简单吗?是的,但是…
ServicedComponent
要求您对程序集进行签名,许多开发人员认为这步是不必要的复杂化。- 您无法在一个类中混合事务性和非事务性方法,这会强制您将单个逻辑
CustomerService
分割为CustomerReader
和CustomerWriter
或类似的东西。
未来:.NET 2.0 中的 TransactionScope
在 .NET 2.0 中,我们将拥有 TransactionScope
类,它解决了这两个问题。它用作围绕必须在数据库事务内运行的代码的大括号,虽然不再是声明式风格,但它提供了一个简洁明了的模型。
using (TransactionScope scope = new TransactionScope())
{
// open connection
// perform database operation, which is going to run inside the transaction
…
// call other method and if the other method creates a TransactionScope object
// it will share the transaction with the current method
// All is well:
Scope.Complete();
}
未来已来
好的,上面的代码看起来像我希望的那样,但是 Whidbey 离我的生产机器还有一年的时间。我必须使用 .NET 1.1 创建我自己的解决方案,这就是它。事实上,实现非常简单,我现在为自己没有早点弄清楚而感到羞愧!
用法
using (TransactionScope scope = new TransactionScope())
using (SqlConnection conn = new SqlConnection(connString))
using (SqlCommand cmd = new SqlCommand(updateSql, conn))
{
System.Diagnostics.Debug.Assert(
System.EnterpriseServices.ContextUtil.IsInTransaction);
conn.Open();
int result = cmd.ExecuteNonQuery();
// We call it success if exactly one record was updated:
if (result == 1)
{
scope.Complete();
}
}
这是完整的类
// Copyright (c) 2005 Alexander Shirshov
//
// This code is free software; you can redistribute it and/or modify it.
// However, this header must remain intact and unchanged. Additional
// information may be appended after this header. Publications based on
// this code must also include an appropriate reference.
//
// This code is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE.
using System;
using System.EnterpriseServices;
namespace Omnitalented.EnterpriseServices
{
public class TransactionScope : IDisposable
{
private bool succeded;
public TransactionScope() : this(TransactionOption.Required,
TransactionIsolationLevel.Any, 60)
{
}
public TransactionScope(TransactionOption transactionOption) :
this(transactionOption, TransactionIsolationLevel.Any, 60)
{
}
public TransactionScope(TransactionOption transactionOption,
TransactionIsolationLevel isolationLevel, int timeoutSeconds)
{
ServiceConfig cfg = new ServiceConfig();
cfg.Transaction = transactionOption;
cfg.IsolationLevel = isolationLevel;
cfg.TransactionTimeout = timeoutSeconds;
ServiceDomain.Enter(cfg);
}
public void Complete()
{
succeded = true;
}
public void Dispose()
{
if (succeded)
{
ContextUtil.SetComplete();
}
else
{
ContextUtil.SetAbort();
}
ServiceDomain.Leave();
}
}
}
请注意:该代码仅适用于 Windows 2003 Server 或 Windows XP;这是 System.EnterpriseServices.ServiceDomain
类的要求。