3

のドキュメントでは、セッションはトランザクションを定義する粒度の単位であり、現在開いているテーブル内のカーソルの位置を定義し、現在アクティブなインデックスを定義するJetBeginSessionことに注意してください。1 つのセッションでは、他に何もできません。しかし、彼らは次のことに注意しています。

データベースへの同時実行性と並列アクセスを向上させるために、複数のセッションを開始できます。

それが私が望むものです。データベースへの 2 番目のセッションを開きたいと思います。

バックグラウンド

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- 1 つのセッションのみがデータベースに接続できるようにします。通常、複数のセッションでデータベースを開くことができます。 (私のものを強調)

単純なアプローチは、別のセッションを開始することです。

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

JetDetachDatabase2 番目のセッションで への呼び出しがハングすることを除きます。

  • のドキュメントを確認してJetDetachDatabaseも何の助けにもなりません。
  • を確認すると、JetAttachDatabase気になることがあります。

別のセッションによって既にアタッチされているデータベースをアタッチしようとするとエラーになることを示すエラー コードがあります。

JET_errDatabaseSharingViolation: データベース ファイルは、別のセッションによって既にアタッチされています。

複数のセッションを開く方法は?

だから今はあまりにも無作為に動揺するのではなく、正しい方法を尋ねます.

Extensible Storage Engine で複数のセッションを開始する方法

ボーナス

私はやや無作為に動き回りました。への呼び出しJetDetachDatabaseがハングしている場合は、呼び出さないようにしましょう。文書化された規則に完全に違反しています。

  • JetOpenDatabaseJetAttachDatabase最初に電話しなければならないと言う
  • 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);

そして、実際にそれうまくいくようです。

...わーい?

4

1 に答える 1

3

「フレアリング」で行ったことは、複数のセッションからデータベースにアクセスする正しい方法でした。

JetAttachDatabase()ファイルを開き、インスタンスに関連付けます。一度だけ呼び出す必要があります。

JetOpenDatabase()セッション内でデータベースへのハンドルを開き、各セッションで呼び出すことができます。

于 2016-05-19T19:42:39.293 に答える