【问题标题】:How do I safely use ADO.NET IDbConnection and IDbCommand to execute multiple database commands concurrently?如何安全地使用 ADO.NET IDbConnection 和 IDbCommand 同时执行多个数据库命令?
【发布时间】:2010-02-05 11:25:54
【问题描述】:

目标

鉴于ADO.NET 实现是在运行时指定的,请使用 ADO.NET IDbConnection 和 IDbCommand 同时针对同一个数据库执行多个命令。

调查

IDbConnection 的 MSDN 文档未指定任何线程限制。 SqlConnection 页面的标准免责声明说“任何实例成员都不能保证是线程安全的。IDbCommandSqlCommand 文档同样不提供信息。

假设没有单个实例成员是线程安全的,我仍然可以从一个连接(在同一个线程上)创建多个命令,然后在不同的线程上同时执行它们。

大概这仍然无法达到预期的效果,因为(我假设)在与数据库的单个底层连接上一次只能执行一个命令。因此并发的IDbCommand 执行将在连接处被序列化。

结论

所以这意味着我们必须创建一个单独的IDbConnection,如果你知道你正在使用SqlConnection,这是可以的,因为它支持池化。如果您的 ADO.NET 实现是在运行时确定的,则无法做出这些假设。

这是否意味着我需要实现自己的连接池以支持对数据库的高性能多线程访问?

【问题讨论】:

    标签: c# .net multithreading ado.net


    【解决方案1】:

    您需要管理对实例成员的线程访问,但大多数 ADO 实现都管理自己的连接池。他们通常希望同时运行多个查询。

    我可以根据需要随意打开和关闭尽可能多的连接,并处理在池不可用时可能引发的异常。

    这是一篇关于ADO connection pooling的文章

    【讨论】:

    • 如果pooling不可用会抛出什么异常?是否为此目的定义了一个标准异常,可以在不同的 ADO.NET 提供程序中一致使用?
    • 好吧,现在我确信,如果您使用 ADO,则可以使用池。我不确定会抛出什么异常,但假设池可用并捕获所有异常情况下的所有异常实例,您可能是安全的。
    【解决方案2】:

    如果您在一个线程上创建连接,则不应在其他线程上使用它。命令也是如此。

    但是,您可以在每个线程上创建一个连接,并在它们自己的线程上安全地使用这些对象。

    池用于创建大量短期连接对象。这意味着底层(昂贵的)数据库连接被重用。

    尼克

    【讨论】:

    • 您好,尼克,感谢您的回答。你有没有参考一些文档说“如果你在一个线程上创建一个连接/命令,你不应该在另一个线程上使用它。”?我在 MSDN 上找不到任何相关信息。
    • 您可以在多个线程上使用连接和命令实例成员,只要确保您在任何时候都只有一个线程使用连接/命令。
    猜你喜欢
    • 2011-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-05
    • 2022-07-25
    • 2016-11-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多