none
MFC+ADOでmdbファイルを作るとロックされる、または最終レコードが作成されない RRS feed

  • 質問

  • VisualStudio2010 C++MFC+ADOで mdbファイルの作成/読み書き を行っています。

    ご質問は2つあります。

    質問1
    既存のmdbファイルをCopyFileを使ってrenameにし新たなファイル(aaa.mdbとします)にコピーした後、
    ADOを使ってaaa.mdbを開き、テーブルを作成した後、レコードを数個作成して、 テーブルセットをClose+CDaoDatabase::Close+AfxDaoTerm()すると、aaa.mdbと別にaaa.ldbが出来てしまって、aaa.mdbがロックされた形になります。
    このロックがかからないようにする方法はありますでしょうか ?
    (テーブルセットClose/CDaoDatabase::Close/AfxDaoTerm() 以外に何かが足りないのかもしれません)


    質問2
    質問1を回避する為
    既存のmdbファイルを CopyFileを使って一時ファイルにコピーした後、
    ADOを使って一時ファイルをオープンして、1つのテーブルに幾つかのレコードを追加したあと、
    一時ファイルをCopyFileを使って別のファイルを作成し、一時ファイルは削除します。 これでロックは回避できますが、
    最終的に作成したファイルには幾つか追加したレコードの最終レコードだけが作成されていません。
    これの回避方法はありますでしょうか ?


    よろしくお願い致します。

    2017年1月15日 8:41

回答

すべての返信


  • 質問2
    質問1を回避する為
    既存のmdbファイルを CopyFileを使って一時ファイルにコピーした後、
    ADOを使って一時ファイルをオープンして、1つのテーブルに幾つかのレコードを追加したあと、
    一時ファイルをCopyFileを使って別のファイルを作成し、一時ファイルは削除します。 これでロックは回避できますが、
    最終的に作成したファイルには幾つか追加したレコードの最終レコードだけが作成されていません。
    これの回避方法はありますでしょうか ?


    よろしくお願い致します。

    自己Resです。

    2番の方はレコードが全部書き出されてない状態で CopyFileしていたようです。  レコードを追加してCloseした後、

    2~3秒Sleepさせると全部書き出されてました。(いちおう問題解決)

    しかし、ADOの書き出しの終了タイミングが正確にわからないので少し危険です。

    何とか質問1の方で対処したいです。

    質問1を補足すると、プログラムを起動したまま、mdbファイルを作成した場合になります。(プログラムを閉じるとldbも削除されます)

    2017年1月15日 9:41
  • ロックファイルが残りロック状態となるということは単純に考えて、正しくクローズ処理が行われていないからであり、コピーで回避するのは問題に対して正面から向き合うことを放棄している印象です。その上で、何を解決したいのでしょうか? 解決すべきは正しくクローズすることであり、そうであればコードを提示し正しくない処理を見極めるべきではないでしょうか?
    2017年1月16日 0:45
  • 佐祐理 さんのおっしゃる通りだと思います。

    その上で、正しく処理しているつもりだが、結果としてロックしたままにになってしまうということであれば、コードを見なければ判断が付きません。短めの再現コードを提示すれば、適切な助言が得られると思います。

    問題を簡潔に再現するプロジェクト一式を提示してはどうでしょうか?

    2017年1月16日 1:35
  • 皆様ご回答ありがとうございました。

    だいぶ時間がかかりましたがなんとか解決しました。

    _RecordsetPtr を CloseだけではなくてReleaseする必要があるようだったので、これを追加したら Lockから抜けることができました。

    2017年1月16日 7:23
  • さん、解決してよかったですね。

    このスレッド自体も Fix するために、佐祐理 さんのコメントに「回答の候補に設定」を押しましょう!

    2017年1月16日 8:49
  • コードが提示されなかったので確実なことは言えませんが、_RecordsetPtrという名称から推測するにCOMスマートポインター_COM_SMARTPTR_TYPEDEFで作成される_com_ptr_tクラス)を使用されていると思われます。「Releaseする必要がある」とのことですが、COMスマートポインターは正しく扱えばAddRef() / Release()は適切なタイミングで自動的に呼び出されるため、ソースコード上に明示的に呼び出す必要はありません。
    • 回答としてマーク AppKey 2017年1月16日 10:48
    2017年1月16日 9:05