2

我正在使用线程池进行一些繁重的处理以及一些 sql。目前,我在需要时打开 sql 连接,运行查询然后关闭它们。这工作正常。该应用程序一直在运行,没有任何问题。随着此应用程序正在完成更多工作,它正在使用更多线程。更多线程意味着更多打开/关闭 SQL 连接。在 SQL 2005 中,这实际上会影响服务器。我的测试服务器每秒处理大约 175 个事务。其中大约 150 个正在主数据库中运行,并且是“ValidateSQLLogin”。

我将更改应用程序,以便每个线程都有自己的连接,然后这个连接在线程周围传递。

所以我的问题是:

如果 SQL 连接对象是在线程中本地创建的,然后通过 ref 传递给另一个类的静态函数,这会不安全吗?

void ThreadA()
{
    SqlConnection a = new SqlConnection(....);
    MyStaticClass.DoStuff(ref a);
}

void ThreadB()
{
    SqlConnection b = new SqlConnection(....);
    MyStaticClass.DoStuff(ref b);
}

static void MyStaticClass.DoStuff(ref SqlConnection sql)
{
    // Do stuff with sql
}

我最初的想法是这将是不安全的,因为 10 个线程可以同时调用同一个静态函数,每个线程都传递自己的连接对象。

以前,静态函数会打开自己的连接,并在完成后关闭它们。

如果不安全,那么解决此问题的最佳方法是什么。我需要尝试最小化 Sql 连接的打开/关闭。

谢谢

加雷斯

4

6 回答 6

5

静态函数的参数与静态字段不同。静态函数的每次执行都将使用不同的连接副本。您甚至不需要将参数作为参考(仅当您想更改参考参数时才需要参考参数)。

于 2009-03-13T12:17:50.657 回答
2

每个线程都有自己的堆栈,参数和局部变量都存储在堆栈上,因此多个线程调用同一个静态方法是没有问题的。每个方法调用都有自己的参数和局部变量。

但是,没有理由SqlConnection通过引用传递该方法。

于 2009-03-13T12:23:14.577 回答
0

正如其他人所说,从多个线程调用静态方法本身并不危险。但是,如果静态方法修改/访问静态字段*,而不是仅使用您传递的参数,则需要使其成为线程安全的。

  • 例外:某些值类型使用原子操作进行访问/写入,并且对于这些操作是隐式线程安全的。但是,在检索和更新这些的逻辑中仍可能出现竞争条件。
于 2009-03-13T12:32:37.923 回答
0

如果您有大量事务,我建议您保持一个静态连接,当您有此事务时保持打开状态,当负载大大减少或为空时,它会自动关闭,并在有新请求时再次打开。

于 2009-03-13T13:02:12.610 回答
0

尝试以下操作:

您可以使用lock语句来防止其他线程进入您正在使用此连接的代码块,其他线程会自动等待前一个线程完成后再进入此段。只需确保您锁定的对象对您的静态类是私有的。

于 2009-03-13T13:12:42.507 回答
-2

在 .Net 中,所有静态成员都是线程安全的。

于 2009-03-13T12:34:15.423 回答