如何使用可扩展存储引擎开始多个会话
How to begin multiple sessions with Extensible Storage Engine
在 JetBeginSession
的文档中,它指出 session 是定义事务的粒度单位,它定义了游标所在的位置在您当前打开的 table 中,它定义了当前活动的索引。在一个 session 上没有别的可以做。但他们确实注意到:
To increase concurrency and parallel access to the database, multiple sessions can be begun.
这是我想要的。我想打开第二个 session 到数据库。
背景
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);
一切正常。
但是我们如何打开另一个session?
ESE 文档虽然稀疏,但确实暗示了可以让多个 session 用于同一数据库的能力:
- To increase concurrency and parallel access to the database, multiple sessions can be begun.
JET_bitTableDenyRead
- The table cannot be opened for read-access by another database session. (implying that sometimes it can be opened for read-access by another session)
JET_bitTableDenyWrite
- The table cannot be opened for write-access by another database session. (implying that sometimes it can be opened for write-access by another session)
JetOpenDatabase
- This function can be called multiple times for the same database.
JET_bitDbExclusive
- Allows only a single session to attach a database. Normally, several sessions can open a database. (emphasis mine)
天真的方法是开始另一个 session:
//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);
除了在第二个 session 中对 JetDetachDatabase
的调用挂起。
- 检查
JetDetachDatabase
的文档没有任何帮助。
- 检查
JetAttachDatabase
我们发现了一些令人担忧的事情。
有一个错误代码,暗示尝试附加一个已经被不同的数据库附加的数据库是错误的 session:
JET_errDatabaseSharingViolation: The database file has already been attached by a different session.
如何打开多个session?
所以现在,与其胡思乱想,不如问问正确的方法。
How to begin multiple sessions with Extensible Storage Engine
奖金
我确实有点随机地连枷。如果对 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);
它实际上似乎喜欢它碰巧工作。
...是吗?
您在 "flailing" 中所做的是从多个会话访问数据库的正确方法。
JetAttachDatabase()
打开文件并将其与实例相关联。只需调用一次。
JetOpenDatabase()
在会话中打开一个数据库句柄,并且可以在每个会话中调用。
在 JetBeginSession
的文档中,它指出 session 是定义事务的粒度单位,它定义了游标所在的位置在您当前打开的 table 中,它定义了当前活动的索引。在一个 session 上没有别的可以做。但他们确实注意到:
To increase concurrency and parallel access to the database, multiple sessions can be begun.
这是我想要的。我想打开第二个 session 到数据库。
背景
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);
一切正常。
但是我们如何打开另一个session?
ESE 文档虽然稀疏,但确实暗示了可以让多个 session 用于同一数据库的能力:
- To increase concurrency and parallel access to the database, multiple sessions can be begun.
JET_bitTableDenyRead
- The table cannot be opened for read-access by another database session. (implying that sometimes it can be opened for read-access by another session)JET_bitTableDenyWrite
- The table cannot be opened for write-access by another database session. (implying that sometimes it can be opened for write-access by another session)JetOpenDatabase
- This function can be called multiple times for the same database.JET_bitDbExclusive
- Allows only a single session to attach a database. Normally, several sessions can open a database. (emphasis mine)
天真的方法是开始另一个 session:
//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);
除了在第二个 session 中对 JetDetachDatabase
的调用挂起。
- 检查
JetDetachDatabase
的文档没有任何帮助。 - 检查
JetAttachDatabase
我们发现了一些令人担忧的事情。
有一个错误代码,暗示尝试附加一个已经被不同的数据库附加的数据库是错误的 session:
JET_errDatabaseSharingViolation: The database file has already been attached by a different session.
如何打开多个session?
所以现在,与其胡思乱想,不如问问正确的方法。
How to begin multiple sessions with Extensible Storage Engine
奖金
我确实有点随机地连枷。如果对 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);
它实际上似乎喜欢它碰巧工作。
...是吗?
您在 "flailing" 中所做的是从多个会话访问数据库的正确方法。
JetAttachDatabase()
打开文件并将其与实例相关联。只需调用一次。
JetOpenDatabase()
在会话中打开一个数据库句柄,并且可以在每个会话中调用。