在 的文档中JetBeginSession
,它指出会话是定义事务的粒度单位,它定义了光标在当前打开的表中的位置,它定义了当前活动的索引。在一次会议上,没有其他事情可以做。但他们确实注意到:
为了增加对数据库的并发和并行访问,可以开始多个会话。
这就是我想要的。我想打开数据库的第二个会话。
背景
ESE 的运行方式有些复杂:
JetCreateInstance(out instance, "UniqueInstanceName"); //Create a uniquely named instance of the ESE in our process
JetInit(instance); //initialize the instance
JetBeginSession(instance, out sessionID); //initialize a session on the instance
JetAttachDatabase(sessionID, filename); //attach a database file to our session
JetOpenDatabase(sessionID, filename, "", out databaseID, 0); //open the database file in our session
//...now we can open table, get data, etc
//E.g. JetOpenTable(sessionID, databaseID, "Customers", null, 0, JET_bitTableReadOnly, out tableID);
JetCloseDatabase(sessionID, databaseID);
JetDetachDatabase(sessionID, filename);
JetEndSession(sessionID, 0);
JetTerm(instance);
这一切都有效。
但是我们如何打开另一个会话呢?
ESE 文档虽然很少,但确实暗示了为同一个数据库进行多个会话的能力:
- 为了增加对数据库的并发和并行访问,可以开始多个会话。
JET_bitTableDenyRead
- 无法打开该表以供另一个数据库会话进行读取访问。(暗示有时它可以被另一个会话打开以供读取访问)JET_bitTableDenyWrite
- 无法打开该表以供另一个数据库会话进行写访问。(暗示有时它可以被另一个会话打开以进行写访问)JetOpenDatabase
- 对于同一个数据库,可以多次调用此函数。JET_bitDbExclusive
- 仅允许单个会话附加数据库。通常,几个会话可以打开一个数据库。 (强调我的)
天真的方法是开始另一个会话:
//Startup the instance
JetCreateInstance(out instance, "UniqueInstanceName");
JetInit(instance);
//Make first session
JetBeginSession(instance, out sessionID);
JetAttachDatabase(sessionID, filename);
JetOpenDatabase(sessionID, filename, "", out databaseID, 0);
//Startup second session
JetBeginSession(instance, out session2ID);
JetAttachDatabase(session2ID, filename);
JetOpenDatabase(session2ID, filename, "", out database2ID, 0);
//Teardown second session
JetCloseDatabase(session2ID, database2ID);
JetDetachDatabase(session2ID, filename); <----hangs
JetEndSession(session2ID, 0);
//Teardown first session
JetCloseDatabase(sessionID, databaseID);
JetDetachDatabase(sessionID, filename);
JetEndSession(sessionID, 0);
//Terminate instance
JetTerm(instance);
除了JetDetachDatabase
第二个会话中的调用挂起。
- 检查文档
JetDetachDatabase
没有帮助。 - 检查
JetAttachDatabase
我们遇到了一些令人担忧的事情。
有一个错误代码暗示尝试附加已由不同会话附加的数据库是错误的:
JET_errDatabaseSharingViolation:数据库文件已被另一个会话附加。
如何打开多个会话?
因此,现在与其太随意地连枷,不如寻求正确的方法。
如何使用可扩展存储引擎开始多个会话
奖金
我确实有些随意地连枷。如果呼叫JetDetachDatabase
挂起,我们就不要打电话了!它完全违反了记录在案的规则:
JetOpenDatabase
说我必须先JetAttachDatabase
打电话JetAttachDatabase
说我必须打电话JetDetachDatabase
但是尝试一下:
//Startup the instance
JetCreateInstance(out instance, "UniqueInstanceName");
JetInit(instance);
//Make first session
JetBeginSession(instance, out sessionID);
JetAttachDatabase(sessionID, filename);
JetOpenDatabase(sessionID, filename, "", out databaseID, 0);
//Startup second session
JetBeginSession(instance, out session2ID);
JetOpenDatabase(session2ID, filename, "", out database2ID, 0);
//Teardown second session
JetCloseDatabase(session2ID, database2ID);
JetEndSession(session2ID, 0);
//Teardown first session
JetCloseDatabase(sessionID, databaseID);
JetDetachDatabase(sessionID, filename);
JetEndSession(sessionID, 0);
//Terminate instance
JetTerm(instance);
它实际上似乎恰好起作用。
...耶?