它对开放式数据库连接有什么影响?使用"块?

时间:2015-07-02 08:53:59

标签: c# database oracle garbage-collection

我试图在SO上搜索这个,但无法找到它。也许我没有正确搜索,这是一个重复的东西。

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

为了澄清我的意思,请查看下面的代码段。

我们打开外部数据库连接的片段"使用"块:

if (!locationManager.isProviderEnabled( LocationManager.GPS_PROVIDER )) {
    buildAlertMessageNoGps();
}

rootView = inflater.inflate(R.layout.fragment_alert, container, false);
[...]

使用"在"中打开数据库连接的片段。块:

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

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

我不会在哪里打开连接"使用"如果出现异常仍会关闭它还是会保持打开状态?

3 个答案:

答案 0 :(得分:1)

由于您没有在连接对象上使用连接,如果发生异常,连接将保持打开状态...所以您需要最终阻止连接,即使存在异常。

所以你的代码将是,因为你没有申请使用连接对象

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

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

答案 1 :(得分:1)

  

我不打开“使用”内部连接的块是否会在异常的情况下关闭它或者是否会保持打开状态?

在这两个例子中,连接仍然是开放的,直到终结者可能会运行,如果有的话。没有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将保证Dispose()调用它,无论代码块是否因异常而停止。您的代码不会使用dbConn执行此操作。

因此,如果您没有明确调用dbConn.Dispose()dbConn.Close()dbConn.Dispose()几乎肯定会调用),则连接将不会关闭。

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

答案 2 :(得分:0)

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