我不明白在多线程环境中使用带有静态成员的静态类时幕后发生了什么。 我有一个服务器应用程序,其中客户端经常读写SQL数据库。为此,我创建了静态类,包括静态成员SQLConnection,SLQDataReader等。但据我所知,静态类只是一个,在线程之间共享,那么它如何同时处理多个请求呢?是不是更好只是用于非静态类? 谢谢!
答案 0 :(得分:4)
我将与其他答案背道而驰,并说将SqlConnection
特别是SqlDataReader
作为全球状态是一个非常糟糕的主意。这是一种巨大的巨大设计气味。需要考虑的几个问题:
连接是否始终保持打开状态?如果是这样 - 您是否知道这会浪费数据库服务器上的资源,甚至可能导致您超过许可连接数?
如果连接不会保持打开状态 - 您将采取哪些步骤来防止一个线程关闭连接而另一个线程正在使用的情况?事实上,您的代码甚至不一定需要多线程才能实现这一点;为了防止它,每个数据库操作必须首先保存原始连接状态,如果关闭则打开连接,然后在完成后恢复原始状态。
您是否正在序列化对SqlConnection
的访问权限?如果是这样,您是否会在整个数据库操作期间锁定它,这将通过导致大量不必要的等待时间严重影响整体应用程序性能?
如果您没有序列化访问权限,当一个操作尝试执行某些不相关的操作而另一个操作正在重要事务中时会发生什么?
如果制作一个“全局”SqlDataReader
,你是否可以绝对确定一次只有一个线程会使用它,并且该线程在完成之前永远不需要执行另一个查询第一个结果集?即使SqlDataReader
是线程安全的(它不是),如果您实际销毁了有问题的对象并将其替换为新对象,则线程安全规则也会超出窗口。
SqlConnection
应该被视为一个工作单元 - 您需要时创建它,并在完成后处理它。 SqlDataReader
甚至不是一个工作单元 - 它是一个一次性的对象,完全没有理由保持在全球范围内。即使你像其他人明显建议的那样实施单身人士,你也会在以后遇到大量麻烦。
更新:如果这些“成员”实际上是工厂方法,那就不同了。这个问题措辞的方式意味着实际上正在共享一个单一的连接。如果您只是为创建连接/查询提供静态方法,那么您可以忽略它。
答案 1 :(得分:1)
只要您只使用静态方法而不使用静态字段,就应该没问题。一旦您决定使用第一个静态字段,就必须担心线程安全。