如何使用可扩展存储引擎

时间:2016-03-06 18:14:47

标签: winapi esent

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);

实际上似乎就像 发生 一样。

...耶?

1 个答案:

答案 0 :(得分:2)

你在&#34; flailing&#34;中做了什么是从多个会话访问数据库的正确方法。

JetAttachDatabase()打开文件并将其与实例关联。它只需要调用一次。

JetOpenDatabase()在会话中打开数据库句柄,可以在每个会话中调用。