且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

SQL Server 2008 R2(.Net 2.0 应用程序)中的死锁问题

更新时间:2023-02-06 21:56:14

检查这个 MSDN 文章 指出:

隔离级别具有连接范围的范围,并且一旦设置为与 SET TRANSACTION ISOLATION LEVEL 语句连接,它在连接关闭或其他隔离之前一直有效级别已设置.当连接关闭并返回池时,上一个 SET TRANSACTION ISOLATION LEVEL 的隔离级别声明被保留.重用池的后续连接连接使用当时有效的隔离级别连接是池化的.

An isolation level has connection-wide scope, and once set for a connection with the SET TRANSACTION ISOLATION LEVEL statement, it remains in effect until the connection is closed or another isolation level is set. When a connection is closed and returned to the pool, the isolation level from the last SET TRANSACTION ISOLATION LEVEL statement is retained. Subsequent connections reusing a pooled connection use the isolation level that was in effect at the time the connection is pooled.

问题是使用 Serializable 隔离级别打开连接;关联的事务被释放,连接也是如此,但连接没有被破坏并进入连接池.下一次(使用相同的连接字符串)发出连接请求时,该连接将被返回,并且由于查询未指定任何隔离级别,因此它在 Serializable 隔离级别中执行.

The issue was that a connection gets opened with Serializable isolation level; the associated transaction was disposed and so was the connection but the connection was not destroyed and went to the connection pool. Next time when a request for a connection was made (with same connection string) this very connection was getting returned and since the query did not specify any isolation level, it was executing in the Serializable isolation level.

基本上,如果您有一个连接池并以特定的隔离级别打开一个连接,比如说 Serializable,那么该连接将返回到隔离级别设置为 Serializable 的池.下次您请求连接时,您无法确定不会返回此连接,因此即使默认隔离级别为 ReadCommitted,您也可能会获得这些可序列化"连接之一.

Basically, if you have a connection pool and open a connection in a particular isolation level, let's say Serializable, then the connection will go back to the pool with the isolation level set to Serializable. Next time you request a connection, you can't be sure that this connection will not be returned so even through the default isolation level is ReadCommitted you may get one of these "Serializable" connections.

另一个需要注意的是,每次将隔离级别设置为可序列化(或其他任何东西)时,您可能会选择不同的连接,并且通过将隔离级别设置为可序列化,您可能会慢慢污染连接池中越来越多的连接(或任何你设置的).

Another caveat is that each time you set the isolation level to Serializable (or anything else for that matter) you may be picking different connections and slowly you may pollute more and more connections in the connection pool by setting their isolation level to Serializable (or whatever you set).

我没有找到任何机制来重置处理连接(当它在执行我的查询后返回连接池时).一种解决方法是显式重置每个连接的隔离级别.但这很乏味.

I didn't find any mechanism to reset the disposing connection (when it was going back to the connection pool after executing my query). One workaround is to explicitly reset the isolation level for each connection. But this is tedious.

所以***的选择是为不同的隔离级别创建单独的连接池.