&是什么QUOT;打开连接"实际上意味着什么呢? [英] What does "opening a connection" actually mean?

查看:297
本文介绍了&是什么QUOT;打开连接"实际上意味着什么呢?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图解释给别人为什么数据库连接实现IDisposable,当我意识到我真的不知道什么是打开连接实际上意味着。结果
所以我的问题是 - 什么是C#实际上,当它打开一个连接呢?

I was trying to explain to someone why database connections implement IDisposable, when I realized I don't really know what "opening a connection" actually mean.
So my question is - What does c# practically do when it opens a connection?

感谢您。

推荐答案

有实际参与实施的连接​​两班(实际上是多了,但我简化)。

There are actually two classes involved in implementing a connection (actually more, but I'm simplifying).

其中一个是在的IDbConnection 实施(的SQLConnection NpgsqlConnection ,您在code使用的OracleConnection 等)。另一种是真实的连接对象,它是内部的装配和不可见您code。我们将这个 RealConnection 就目前而言,虽然它的实际名称与不同的实现方式不同(例如,在Npgsql,这就是我最熟悉的执行案件,该类称为 NpgsqlConnector )。

One of these is the IDbConnection implementation (SQLConnection, NpgsqlConnection, OracleConnection, etc.) that you use in your code. The other is a "real" connection object that is internal to the assembly, and not visible to your code. We'll call this "RealConnection" for now, though its actual name differs with different implementations (e.g. in Npgsql, which is the case where I'm most familiar with the implementation, the class is called NpgsqlConnector).

当您创建的IDbConnection ,它没有一个 RealConnection 。任何试图做的数据库将失败的东西。当你打开()然后会发生以下情况:

When you create your IDbConnection, it does not have a RealConnection. Any attempt to do something with the database will fail. When you Open() it then the following happens:


  1. 如果启用了连接池,并有一个 RealConnection 池,双端队列并使其在 RealConnection 的IDbConnection

  2. 如果启用了连接池,和 RealConnection 总数对象存在大于最大尺寸,抛出异常。

  3. 否则,创建一个新的 RealConnection 。初始化它,这将涉及开放某种网络连接(例如TCP / IP)或文件句柄(这样的事情接入),通过数据库的协议握手(与数据库类型而有所不同),并授权连接。这便成为 RealConnection 的IDbConnection

  1. If pooling is enabled, and there is a RealConnection in the pool, deque it and make it the RealConnection for the IDbConnection.
  2. If pooling is enabled, and the total number of RealConnection objects in existence is larger than the maximum size, throw an exception.
  3. Otherwise create a new RealConnection. Initialise it, which will involve opening some sort of network connection (e.g. TCP/IP) or file handle (for something like Access), go through the database's protocol for hand-shaking (varies with database type) and authorise the connection. This then becomes the RealConnection for the IDbConnection.

上的操作进行了的IDbConnection 都化作行动 RealConnection 做它的网络连接上(或其他) 。结果变成了实施对象的IDataReader 等,从而给出一致的界面编程。

Operations carried out on the IDbConnection are turned into operations the RealConnection does on its network connection (or whatever). The results are turned into objects implementing IDataReader and so on so as to give a consistent interface for your programming.

如果一个的IDataReader CommandBehavior.CloseConnection 创建的,那么DataReader的获得的所有权的 RealConnection

If a IDataReader was created with CommandBehavior.CloseConnection, then that datareader obtains "ownership" of the RealConnection.

当你调用关闭()则发生下列情况之一:

When you call Close() then one of the following happens:


  1. 如果池是池未满,则该对象放入队列以便与以后的操作中使用。

  2. 否则 RealConnection 将开展结束连接(信令连接是否要关闭数据库)的任何协议规定的程序,并关闭网络连接等对象就可以掉出的范围,成为可进行垃圾回收。

  1. If pooling is the pool isn't full, then the object is put in the queue for use with later operations.
  2. Otherwise the RealConnection will carry out any protocol-defined procedures for ending the connection (signalling to the database that the connection is going to shut down) and closes the network connection etc. The object can then fall out of scope and become available for garbage collection.

唯一的例外是,如果 CommandBehavior.CloseConnection 情况下发生的,在这种情况下,它是关闭()的Dispose()正在呼吁的IDataReader 触发此。

The exception would be if the CommandBehavior.CloseConnection case happened, in which case it's Close() or Dispose() being called on the IDataReader that triggers this.

如果你调用的Dispose()那么同样的事情发生按关闭()。不同的是,的Dispose()使用视为清理,可与工作,而关闭()可能一生中的中间被使用,并遵循以后打开()

If you call Dispose() then the same thing happens as per Close(). The difference is that Dispose() is considered as "clean-up" and can work with using, while Close() might be used in the middle of lifetime, and followed by a later Open().

由于使用了 RealConnection 对象,他们汇集的事实,开被东西比较重,以比较轻的关闭连接的变化的。因此,而不是将其作为重要的是保持连接打开很长一段时间,以避免打开它们的开销,让他们打开尽可能短的时间内有可能,就变得很重要,因为 RealConnection 涉及的开销为你和你迅速使用它们,更有效的存储连接得到应用之间共享。更多

Because of the use of the RealConnection object and the fact that they are pooled, opening and closing connections changes from being something relatively heavy to relatively light. Hence rather than it being important to keep connections open for a long time to avoid the overhead of opening them, it becomes important to keep them open for as short a time as possible, since the RealConnection deals with the overhead for you, and the more rapidly you use them, the more efficiently the pooled connections get shared between uses.

还要注意,它的好的Dispose()的IDbConnection 您已经叫关闭()上(这是一个规则,它应该始终安全地调用的Dispose(),无论国家,的确即使已经调用)。因此,如果你是手动调用关闭()它仍然将是很好的有一个使用块的连接,以赶上例外情形调用关闭之前发生的案件()。唯一的例外是你真正想要的连接保持开放;说你返回一个的IDataReader CommandBehavior.CloseConnection 创建的,在这种情况下,你不处理的的IDbConnection ,但配置读卡器。

Note also, that it's okay to Dispose() an IDbConnection that you have already called Close() on (it's a rule that it should always be safe to call Dispose(), whatever the state, indeed even if it was already called). Hence if you were manually calling Close() it would still be good to have the connection in a using block, to catch cases where exceptions happen before the call to Close(). The only exception is where you actually want the connection to stay open; say you were returning an IDataReader created with CommandBehavior.CloseConnection, in which case you don't dispose the IDbConnection, but do dispose the reader.

您应该失败处置的连接,那么 RealConnection 不会返回到池中供重新使用,或通过其关闭程序。任一池将达到它的极限,或底层连接的数目将增加到破坏性能和正在创建阻断更多的点。最终,在 RealConnection 的finaliser可称为并导致这个固定的,但最后确定只降低了损坏,不能依赖时。 (在的IDbConnection 不需要finaliser,因为它是 RealConnection 持有的非托管资源和/或需要做关机)。

Should you fail to dispose the connection, then the RealConnection will not be returned to the pool for reuse, or go through its shut-down procedure. Either the pool will reach its limit, or the number of underlying connections will increase to the point of damaging performance and blocking more from being created. Eventually the finaliser on RealConnection may be called and lead to this being fixed, but finalisation only reduces the damage and can't be depended upon. (The IDbConnection doesn't need a finaliser, as it's the RealConnection that holds the unmanaged resource and/or needs to do the shut-down).

这也是合理的假设,有处置独有的的IDbConnection 超出了本实施一些其他的要求,仍应进行处理,即使分析的以上导致你相信它不是必需的(例外是当 CommandBehavior.CloseConnection 通过了所有的处理负担,的IDataReader ,但随后处置该阅读器)是同样重要的。

It's also reasonable to assume that there is some other requirement for disposal unique to the implementation of the IDbConnection beyond this, and it should still be disposed of even if analysing the above leads you to believe its not necessary (the exception is when CommandBehavior.CloseConnection passes all disposal burden to the IDataReader, but then it is just as important to dispose that reader).

这篇关于&是什么QUOT;打开连接"实际上意味着什么呢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆