通过singleton类获取数据库连接

时间:2009-05-02 05:27:55

标签: c# design-patterns singleton

我创建了一个单例类,这个类返回一个数据库连接。所以我的问题是这种联系也满足单身标准吗? 如果不是,那么我怎么能把它变成单身 这是代码。

public sealed class SingletonDB
{
    static readonly SingletonDB instance = new SingletonDB();
    static SqlConnection con =new SqlConnection(ConfigurationManager.ConnectionStrings["mydb"].ConnectionString);

    // Explicit static constructor to tell C# compiler
    // not to mark type as beforefieldinit
    static SingletonDB()
    {
    }

    SingletonDB()
    {
    }

    public static SingletonDB Instance
    {
        get
        {
            return instance;
        }
    }

    public static SqlConnection GetDBConnection()
    {
        return con;
    }
}

6 个答案:

答案 0 :(得分:27)

你的单身人士仍在休息。

就单身人士模式而言,请参阅Jon Skeet的详细描述:http://www.yoda.arachsys.com/csharp/singleton.html

使用Singleton作为SqlConnection对象是一个非常非常糟糕的主意。没有理由这样做。

如果您试图避免“new SqlConnection()”或“connection.Open()”的性能损失,请注意由于连接池在幕后进行,确实没有性能损失。连接池处理 昂贵的 连接的打开/关闭。不是SqlConnection对象。

如果您尝试与多个线程共享同一个连接对象,则无法同时使用该连接打开多个SqlDataReaders / Commands,并且会遇到线程阻塞问题。

Singleton模式是最常使用和滥用的模式,并且您可能没有注意到单身人士的许多副作用。在这里非常好地谈论单身人士的危险http://www.youtube.com/watch?v=-FRm3VPhseI

答案 1 :(得分:4)

连接本身不满足Singleton条件,因为您可以创建数据库连接对象的多个实例。根据定义,单例只能实例化一次。

可以使SqlConnection成为Singleton的一部分,将你的例子改为:

public sealed class SingletonDB
{
   private static readonly SingletonDB instance = new SingletonDB();
   private readonly SqlConnection con =new SqlConnection(ConfigurationManager.ConnectionStrings["mydb"].ConnectionString);

   // Explicit static constructor to tell C# compiler
   // not to mark type as beforefieldinit
   static SingletonDB()
   {
   }

   private SingletonDB()
   {
   }

   public static SingletonDB Instance
   {
       get
       {
          return instance;
       }
   }

   public SqlConnection GetDBConnection()
   {
       return con;
   }

}

这样,SingletonDB类使用的SqlConnection将只有一个SqlConnection,因此遵循Singleton模式。

答案 2 :(得分:4)

在.NET C#中,您可以像这样编写单例

    public class Singleton{
public static readonly Singleton Instance= new Singleton();
private Singleton(){}

或多线程环境:

using System;

public sealed class Singleton
{
   private static volatile Singleton instance;
   private static object syncRoot = new Object();

   private Singleton() {}

   public static Singleton Instance
   {
      get 
      {
         if (instance == null) 
         {
            lock (syncRoot) 
            {
               if (instance == null) 
                  instance = new Singleton();
            }
         }

         return instance;
      }
   }
}

答案 3 :(得分:1)

如果没有其他方法可以获得与DB的连接,并且如果不能覆盖此属性,我会说是。如果这就是你正在做的事情,你可能会把这个单身人士的事情搞得太过分了。如果数据库暂时中断并且您的应用程序失去连接怎么办?然后,您必须重新启动应用程序才能再次使用该数据库。

答案 4 :(得分:1)

我认为,如果没有看到某些代码,我就无法回答这个问题。如果您说您的应用程序中只有一个数据库连接实例,那么如果您可以保证您的应用程序只能在一个线程上运行(或至少所有使用数据库连接的操作都运行),那么这可能会有效,因为您可以(据我所知)在同一个连接上并行运行多个操作。

此外,如果这意味着您的应用程序将在两次使用之间保持连接打开,我会建议不要使用它。数据库服务器上的数据库连接是有限的资源,因此只有在需要时才将它们保持打开状态,然后关闭它们。

答案 5 :(得分:1)

Singleton意味着您所创建的类只能实例化一次。因此,如果您希望这样做,请做两件事:

  1. 将构造函数设为私有。(这是为了防止其他类访问它。)
  2. 将类实例化为:

    get
    {
     if(instance == null) //important coz, the class will be instantiated only on the first call
     {
       instance = new singletonDb;
     }
     return instance;
    }