记住.net中的SQL连接状态?

时间:2014-05-30 06:48:53

标签: c# .net connection-pooling dapper sqlconnection

除了connection.Close()connection.Dispose()相同的旧事实之外 - 除了在已处理的连接上运行Close()时会运行Close() 1}}关闭连接 - 没关系 - 我还有一个问题:

假设连接池已打开,(默认) - 为什么是否记住连接状态很重要?

我已阅读this question here,其中显示 - 避免打开和关闭连接可以节省性能

这似乎是逻辑,但问题是连接永远不会实际关闭!只有标记为才能关闭。

即使我在using范围内使用它 - 只需关闭连接并将其放回池中。

即使我想要,我也无法将其打开(因为我希望其他人使用它)。所以我不得不关闭/处理它。

Looking at Dapper也实现了这种行为:

public static async Task<IEnumerable<T>> QueryAsync<T>(this...)
        {
         //...
            bool wasClosed = cnn.State == ConnectionState.Closed;
            using (var cmd = (DbCommand)command.SetupCommand(cnn, info.ParamReader))
            {
                try
                {
                    if (wasClosed) await ((DbConnection)cnn).OpenAsync()...
                  //...
                }
                finally
                {
                    if (wasClosed) cnn.Close();
                }
            }
        }

你可以看到&#34;记忆&#34;在这里实施。

nb,我已经向Marc询问了一个相关的主题 - 为什么在短小精悍的样本中他同时使用GetClosedConnecitonGetOpenConnection,我得到了一个答案,表明 - Dapper可以处理这两种情况。但是,目前的问题是关于为什么重新设置连接状态。

问题:

查看Dapper代码,它似乎记得状态并在操作后重新设置状态。 (我也知道旧sqldataadapter类中的这种行为)

问题是 - 为什么?如果我有一个封闭的连接 - 那么,我需要打开它。大。但为什么我必须按条件关闭呢?为什么不总是关闭它?它不会损害性能,因为连接实际上没有关闭 - 它只返回池中。

另一种方式 - 如果我有一个开放的连接,那么我就会工作并保持打开(呵呵??)

你可能已经看到了,我在这里遗漏了一些东西。有人可以光明吗?

2 个答案:

答案 0 :(得分:6)

如果您正在编写库函数,消费者可以通过它传递连接对象(无论什么风格),那么最安全的做法就是尊重这种联系:

  • 如果你通过了一个开放的连接对象,不做任何假设,当你完成工作后肯定不要关闭它 - 你不知道你的消费者有什么完成它或将用它做。
  • 如果您通过了已关​​闭的连接对象,那么您在尝试使用它之前最好打开它,并且在完成后应该关闭它 - 您知道您的消费者不能有例如针对已关闭的连接打开的交易。

如果您的代码创建了一个连接对象,那么我总是建议将创建放在using语句中,这样当您&#39时它将始终关闭;完成。

所以,我能想到的唯一剩下的就是仔细考虑编写你的功能并弄清楚它是否会让你的消费者感觉感觉传递你的连接对象 - 如果你的工作应该总是要孤立地进行,要求例如更有意义连接字符串,代码完全控制连接。

答案 1 :(得分:6)

  

为什么不一直关闭它?

用户可能正在对该连接进行大量工作。它可能与一个事务相关联(关闭它会孤立它)。它可能有临时表(关闭会破坏它们),或其他连接保留状态(SET选项,模拟等)。

在这里关闭连接(如果它最初打开)将是一个不寻常和意想不到的事情,有多种令人讨厌的副作用。