2008-12-05 101 views
3

如何在ASP.Net应用程序中管理数据库连接?连接管理ASP.net

我的理解告诉我,“最好的”方法是打开连接,进行查询,关闭连接,并多次执行此操作,因为连接池使成本变得可忽略不计。

问题来了,当我有一个DAL,其中每个方法看起来自己的连接。例如。

 
User x = DAL.GetUserDetails(); 
Customer y = DAL.GetCustomer(); 

这是罚款,直到我们开始谈论的TransactionScope

 
using (TransactionScope t.... 
{ 
DAL.UpdateCustomer(y); 
DAL.UpdateUser(x); 
t.Complete(); 
} 

ASP.Net想现在使用DTC,因为(我猜)有涉及多个连接。

有人会说“缓存连接somwhere”,但我需要显式销毁连接,因为我管理安全的方式(作为/恢复),我不想打电话每一页都这样做,因为有人会忘记打电话。我也可以将连接传递给每个方法,但这并不理想,因为页面必须管理连接。

我有意义还是错过了一些基本的东西?

回答

1

我正在读某处,我不记得微软将在哪里解决这个问题,当你有两个连接到相同的数据库,他们不会升级到DTC,这将导致此问题消失。

在那之前我们所做的是开发我们的TransactionScope,我们的DAL然后会要求TS建立一个新的连接,当我们放置TS时它会关闭连接。

连接存储在LogicalCallContext中,但我会考虑使用HTTP Context。我在应用程序上线之前离开了公司,但从我听说他们没有遇到任何问题。

所以你必须

using (CustomTS.New()) 
{ 
CustomerDal.Update() 
userDal.Update() 
} 

CustomTS不得不将获得当前的事务和连接的静态方法。

+0

好主意,所以如果我理解正确:在dal方法中,我可以看看TransactionScope.Current。如果它不为null,则使用该事务以及与该事务相关的连接。如果它为空创建一个连接,因为我目前做? – 2008-12-05 01:28:25

+0

我必须先给它一个去,然后我给它一个大的勾号 – 2008-12-05 01:30:26

0

在TransactionContext的工作原理上采用类似的思路实现它。

我开始写如何做到这一点,但我觉得一个例子使它更清晰:

public class MyConnectionManager : IDisposable 
{ 
    [ThreadStatic] // static per thread 
    private static SqlConnection con; 

    public static SqlConnection Connection 
    { 
     get 
     { 
      if (con == null) 
      { 
       con = new SqlConnection(); 
       con.Open(); 
      } 
      return con; 
     } 
    } 

    public void Dispose() 
    { 
     if (con != null) 
     { 
      con.Close(); 
     } 
    } 
} 

public class Program 
{ 
    public void Run() 
    { 
     using(new MyConnectionManager()) 
     { 
      MakeCall(); 
      MakeCall(); 
     } // Disposal happens here 
    } 

    public void MakeCall() 
    { 
     // The property can be accessed from anywhere 
     SqlCommand cmd = new SqlCommand("SELECT 1", MyConnectionManager.Connection); 
    } 
} 

这将导致使用声明范围内的任何呼叫使用相同的连接,只要他们全部在同一个线程上运行。你也可以在那里抛出一个事务上下文。

注意:在ASP.NET WebPages场景中,线程可以在连接和page_load之间切换。 See this article for more info。线程也被重新使用。但是,如果您正在开发在应用程序之间共享的DAL,则可能无法使用HttpContext,因为没有。