在 "using" 块外打开 DB conn 有什么影响?

What effects does it have to opena DB conn outside a "using" block?

我试图在 SO 上搜索此内容,但找不到。可能是我没搜对,是重复的东西。

但我想问一个问题:在 using(...) 块内部和外部打开数据库连接有什么区别。

为了阐明我的意思,请查看下面的代码片段。

我们在 "using" 块外打开数据库连接的片段:

if (_dbConn.State != ConnectionState.Open)
            _dbConn.Open();

        using (var oraclePackage = new OraclePackage())
        { // some DB function here... }

在 "using" 块内打开数据库连接的代码段:

using (var oraclePackage = new OraclePackage())
        {
            if (_dbConn.State != ConnectionState.Open)
                _dbConn.Open();

            // some DB functions here 
        }

在 "using" 中我不打开连接的块是否仍会在出现异常时关闭它,还是会保持打开状态?

Using 语句不处理任何异常。它负责在当前对象(数据库连接)上调用 IDisposable。 这意味着无论您是在 using 块内部还是外部打开连接,在块的末尾都将处理连接

由于您没有在连接对象上应用,如果发生异常,连接将保持打开状态...因此您需要 finally 块,即使出现异常也会关闭您的连接。

因此您的代码将是 ,因为您没有在连接对象上应用

try
{
  using (var oraclePackage = new OraclePackage())
    {
        if (_dbConn.State != ConnectionState.Open)
            _dbConn.Open();

        // some DB functions here 
    }
}
finally
{  _dbConn.Close(); }

Would the block where I DO NOT open a connection inside "using" still close it in case of an exception or would it be left open?

在这两个示例中,连接仍将打开,直到可能出现终结器 运行,如果有人这样做的话。 using 也没有 "using" dbConn.

代码:

using(someObject)
{
  // More code here.
}

相当于:

try
{
  // More code here.
}
finally
{
  if(someObject != null)
    ((IDisposable)someObject).Dispose();
}

代码:

using(var someObject = new SomeClass())
{
  // More code here.
}

相当于:

var someObject = new SomeClass();
try
{
  // More code here.
}
finally
{
  if(someObject != null)
    ((IDisposable)someObject).Dispose();
}

(在对象显然不能在任何时候设置为 null 的情况下,可能会优化空检查)。

您的代码使用 oraclePackage 执行此操作,因此 oraclePackage 将被 gua运行teed 调用 Dispose(),代码块是否由于以下原因而留下例外与否。您的代码不会使用 dbConn.

执行此操作

因此,如果您不显式调用 dbConn.Dispose()dbConn.Close()dbConn.Dispose() 几乎肯定会调用),连接将不会关闭。

如果没有剩余的 GC roots 可以访问 dbConn 那么很可能最终代表实际打开连接的内部对象将被终结,这将导致连接被关闭,但这是不一定运行会发生或不会及时发生,并且很可能无法与大多数 IDbConnection 实现使用的内部缓存机制一起工作。