我想在一个带有
的业务逻辑的.net 2.0项目中进行事务性的一系列sp调用(sql server 2005)using(TransactionScope...)
不幸的是,我从另一个项目继承了DAL,我不想在那里做很多改动。问题是每个调用存储过程的方法都会打开一个新的连接。
所以,我的问题是:有没有办法检索当前事务使用的连接,即来自Transaction.Current ??
谢谢
第
更新:请告诉我这个控制台应用程序有什么问题(vs2005,.net 2.0,Sql server 2005)
using System;
using System.Collections.Generic;
using System.Text;
using System.Data.SqlClient;
using System.Data;
using System.Transactions;
namespace ConsoleApplication1
{
public class Program
{
static void Main(string[] args)
{
using (TransactionScope ts = new TransactionScope(TransactionScopeOption.Required))
{
Console.WriteLine("1");
test();
Console.WriteLine("2");
test();
}
Console.WriteLine("END");
}
public static void test()
{
string connectionString = @"Persist Security Info=True;User ID=usr123;Password=123;Initial Catalog=db123;Data Source=myserver\myinstance;Connect Timeout=180;";
using (SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open();
}
}
}
}
答案 0 :(得分:1)
好的,有几件事:
我怀疑TransactionScope甚至有(Sql)连接的概念。原因是它可以与各种事务资源一起使用,无论是dabatabase,消息排队系统还是其他任何事务资源。您可能需要参考MSDN Docs for System.Transactions以获取更多信息。所以,我猜你的方法注定要失败。
在您的示例中,您错过了“ts.Complete()”调用,因此当using-Scope结束时,您的(分布式)事务将始终回滚。现在,这与你所描述的问题无关,但值得指出。
您的环境事务(由TransactionScope实例类似的环境事务)将传播到分布式事务,因为您在其中使用了多个连接。基本上,系统上的DTC需要与数据库服务器上的DTC通信。为了实现这一点,必须正确配置。
要通过执行C:\Windows\System32\com\comexp.msc
配置DTC,请运行“组件服务”管理控制台。在树视图中,导航到“组件服务\计算机\我的计算机”。在上下文菜单中打开“属性”。在“属性”对话框中,选择“MSDTC”选项卡,单击“安全配置...”按钮。
在对话框中确保选择以下选项:
(注意:其中一些可能实际上不是必需的,YMMV)
您可能还希望设置为“无需身份验证”,具体取决于您当地的政策/要求。
您需要在两个系统上执行此操作:运行应用程序的系统和带有数据库的系统。
答案 1 :(得分:1)
好的,谢谢大家... ..最后我写完了类似你可以在企业库(http://entlib.codeplex.com)中找到的Microsoft.Practices.EnterpriseLibrary.Data.TransactionScopeConnections。
答案 2 :(得分:0)
除非你因为某些原因没有使用连接池,否则没有理由不新建一个SqlConnection并进入城镇。让运行时处理制作该性能的细节 - 这就是连接池的用途。听起来DAL写得正确:
...
using (var conn = new SqlConnection("connection string"))
{
using (var cmd = conn.CreateCommand())
{
conn.Open();
//Do stuff with cmd
}
}
....
即使您没有使用连接池(并且您有正当理由不这样做),最好的路径可能仍然是新建一个SqlConnection并转到城镇。您不希望意外地执行诸如关闭事务范围正在使用的连接之类的事情,并且假设它实际上有一个SqlConnection供您引用。