会话
一个 SQL Server Native Client OLE DB 访问接口会话表示与 SQL Server 实例的单个连接。
SQL Server Native Client OLE DB 访问接口要求会话分隔数据源的事务空间。通过某一特定会话对象创建的所有命令对象均参与该会话对象的本地事务或分布式事务。
在已初始化数据源上创建的第一个会话对象接收在初始化期间建立的 SQL Server 连接。当释放该会话对象的接口上的所有引用时,在该数据源上创建的其他会话对象即可使用与 SQL Server 实例的连接。
在数据源上创建的其他会话对象建立其自身到该数据源指定的 SQL Server 实例的连接。当应用程序释放对创建该会话的对象的所有引用时,将删除与 SQL Server 实例的连接。
下面的示例说明了如何使用 SQL Server Native Client OLE DB 访问接口连接 SQL Server 数据库:
int main()
{
// Interfaces used in the example.
IDBInitialize* pIDBInitialize = NULL;
IDBCreateSession* pIDBCreateSession = NULL;
IDBCreateCommand* pICreateCmd1 = NULL;
IDBCreateCommand* pICreateCmd2 = NULL;
IDBCreateCommand* pICreateCmd3 = NULL;
// Initialize COM.
if (FAILED(CoInitialize(NULL)))
{
// Display error from CoInitialize.
return (-1);
}
// Get the memory allocator for this task.
if (FAILED(CoGetMalloc(MEMCTX_TASK, &g_pIMalloc)))
{
// Display error from CoGetMalloc.
goto EXIT;
}
// Create an instance of the data source object.
if (FAILED(CoCreateInstance(CLSID_SQLNCLI10, NULL,
CLSCTX_INPROC_SERVER, IID_IDBInitialize, (void**)
&pIDBInitialize)))
{
// Display error from CoCreateInstance.
goto EXIT;
}
// The InitFromPersistedDS function
// performs IDBInitialize->Initialize() establishing
// the first application connection to the instance of SQL Server.
if (FAILED(InitFromPersistedDS(pIDBInitialize, L"MyDataSource",
NULL, NULL)))
{
goto EXIT;
}
// The IDBCreateSession interface is implemented on the data source
// object. Maintaining the reference received maintains the
// connection of the data source to the instance of SQL Server.
if (FAILED(pIDBInitialize->QueryInterface(IID_IDBCreateSession,
(void**) &pIDBCreateSession)))
{
// Display error from pIDBInitialize.
goto EXIT;
}
// Releasing this has no effect on the SQL Server connection
// of the data source object because of the reference maintained by
// pIDBCreateSession.
pIDBInitialize->Release();
pIDBInitialize = NULL;
// The session created next receives the SQL Server connection of
// the data source object. No new connection is established.
if (FAILED(pIDBCreateSession->CreateSession(NULL,
IID_IDBCreateCommand, (IUnknown**) &pICreateCmd1)))
{
// Display error from pIDBCreateSession.
goto EXIT;
}
// A new connection to the instance of SQL Server is established to support the
// next session object created. On successful completion, the
// application has two active connections on the SQL Server.
if (FAILED(pIDBCreateSession->CreateSession(NULL,
IID_IDBCreateCommand, (IUnknown**) &pICreateCmd2)))
{
// Display error from pIDBCreateSession.
goto EXIT;
}
// pICreateCmd1 has the data source connection. Because the
// reference on the IDBCreateSession interface of the data source
// has not been released, releasing the reference on the session
// object does not terminate a connection to the instance of SQL Server.
// However, the connection of the data source object is now
// available to another session object. After a successful call to
// Release, the application still has two active connections to the
// instance of SQL Server.
pICreateCmd1->Release();
pICreateCmd1 = NULL;
// The next session created gets the SQL Server connection
// of the data source object. The application has two active
// connections to the instance of SQL Server.
if (FAILED(pIDBCreateSession->CreateSession(NULL,
IID_IDBCreateCommand, (IUnknown**) &pICreateCmd3)))
{
// Display error from pIDBCreateSession.
goto EXIT;
}
EXIT:
// Even on error, this does not terminate a SQL Server connection
// because pICreateCmd1 has the connection of the data source
// object.
if (pICreateCmd1 != NULL)
pICreateCmd1->Release();
// Releasing the reference on pICreateCmd2 terminates the SQL
// Server connection supporting the session object. The application
// now has only a single active connection on the instance of SQL Server.
if (pICreateCmd2 != NULL)
pICreateCmd2->Release();
// Even on error, this does not terminate a SQL Server connection
// because pICreateCmd3 has the connection of the
// data source object.
if (pICreateCmd3 != NULL)
pICreateCmd3->Release();
// On release of the last reference on a data source interface, the
// connection of the data source object to the instance of SQL Server is broken.
// The example application now has no SQL Server connections active.
if (pIDBCreateSession != NULL)
pIDBCreateSession->Release();
// Called only if an error occurred while attempting to get a
// reference on the IDBCreateSession interface of the data source.
// If so, the call to IDBInitialize::Uninitialize terminates the
// connection of the data source object to the instance of SQL Server.
if (pIDBInitialize != NULL)
{
if (FAILED(pIDBInitialize->Uninitialize()))
{
// Uninitialize is not required, but it fails if an
// interface has not been released. Use it for
// debugging.
}
pIDBInitialize->Release();
}
if (g_pIMalloc != NULL)
g_pIMalloc->Release();
CoUninitialize();
return (0);
}
对于持续创建和释放会话对象的应用程序,连接 SQL Server Native Client OLE DB 访问接口会话对象和 SQL Server 实例可生成很大的开销。有效管理 SQL Server Native Client OLE DB 访问接口会话对象可以使此开销降至最低。通过至少维护一个会话对象接口的引用,SQL Server Native Client OLE DB 访问接口应用程序可以使该对象的 SQL Server 连接处于活动状态。
例如,维护命令创建对象引用池将保持该池中这些会话对象的活动连接。由于需要会话对象,因此池维护代码向需要会话的应用程序方法传递有效的 IDBCreateCommand 接口指针。当应用程序方法不再需要该会话时,该方法将接口指针返回到池维护代码,而不是释放应用程序对命令创建对象的引用。
注意 |
---|
在前面的示例中,使用 IDBCreateCommand 接口的原因在于 ICommand 接口实现 GetDBSession 方法,该方法是命令或行集作用域中允许对象确定其创建所在的会话的唯一方法。因此,只有命令对象才允许应用程序检索可创建其他会话的数据源对象指针。 |