質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.65%

ACCESSデータベースアクセス後、ldbが(なかなか)消えない

解決済

回答 2

投稿

  • 評価
  • クリップ 2
  • VIEW 291

Sitapper

score 8

ACCESSデータベースは使用中にロックファイル(*.ldb)を作成しますが、
データベースを閉じた(つもり)なのにこのロックファイルがなかなか消えません。

C:\_Tmp\test.accdb というデータベースを用意し、
ボタンを一つ配置したような簡単な画面を作成してみました。

プロバイダは "Microsoft.Ace.OLEDB.12.0"、
データベース種類は accdb です。 

デバッガでコード中(*C)の行にブレークポイントを置きます。
ボタンを押すとデータベースに接続(db.Connect())を実行し、
すぐに切断(db.Disconnect())を実行します。

エクスプローラを開いて C:\_Tmp\test.accdb を見つつ動作させてみると、

  1. コード中の(*A)の行を実行すると test.ldb が作成される。
    これは、(*A)にブレークポイントを置いてステップ実行し、
    この行が実行された際に test.ldb が作成されたことを予め確認しています。
  2. ソース中(*C)のブレークポイントで止まる。
    しばらくそのまま放置する。
  3. ブレークポイントで止まったまま約80秒経過したあたりで、
    エクスプローラから test.ldb が消える。

つまり、(*B)を実行した後、しばらくして非同期で消えるようなのです。
なぜこんなにも時間がかかるのか、
あるいは、プログラムに誤りなどありましたらお教えください。

ちなみに、以前はこのようなことがなく動いていたように思います。
以前と違う点は、
・Windows7 から 10 に端末を変更した。
・VisualStudio 2017 から 2019 に変更となった。
・Windows7 の端末では Office 2013 が入っていたが、
これには Office365 の 32bit が入っている。

前の Windows7 端末は没収の上初期化されてしまったので、
環境が分からなくなってしまったのですが、
何か必要なものがインストールされていないなどあるでしょうか。
(Accessランタイムなどはこの端末には入れていません。)

どうぞよろしくお願いいたします。

using System;
using System.Windows.Forms;
using System.Data.OleDb; // OleDbConnection...

namespace Test
{
    public partial class Form1 : Form
    {
        public class DB
        {
            public OleDbConnection ConnectionObj {get; private set;}

            public DB() {
                ConnectionObj = null;
            }

            public void Connect()
            {
                if (ConnectionObj == null) {
                    ConnectionObj = new OleDbConnection();
                }

                string provider = "Microsoft.Ace.OLEDB.12.0";
                string source = @"C:\_Tmp\test.accdb";
                string connectionString = $"Provider={provider};Data Source={source}";
                ConnectionObj.ConnectionString = connectionString;
                ConnectionObj.Open(); // <-------- (*A)ここでldbが作成される
            }

            public void Disconnect()
            {
                if (ConnectionObj != null) {
                    ConnectionObj.Close(); // <-------- (*B)ここでldbが破棄されるはず?
                    ConnectionObj.Dispose(); // <-------- (*C)ここでブレークポイント
                    ConnectionObj = null;
                }
            }
        }

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            DB db = new DB();
            db.Connect();
            db.Disconnect();
            db = null;
        }
    }
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • Zuishin

    2020/02/06 20:21

    エクスプローラーは特にコンピューターがビジー状態の時、時間差があることがあります。コマンドプロンプトを開き、dir で消えたかどうかを確認してください。

    また、Dropbox などを使っていると、消したはずのファイルが一時的に復活することがあります。普通のディレクトリであることを確認してください。

    キャンセル

  • Sitapper

    2020/02/06 20:46

    ご覧くださいましてありがとうございます。

    コマンドプロンプトでも見てみましたが、やはり同じように時間がかかっていました。

    ひとつ気づいたのですが、
    ldb ファイルにはアクセス対象の情報が書かれるはずが、サイズが 0 で作成されます。
    そのまま放置しているとしばらく経ってからサイズ 0 のまま消えます。
    (コマンドプロンプトから確認しています。)

    ところが、サイズ 0 で作成された ldb ファイルをエクスプローラでアクセスすると
    (コマンドプロンプトから copy したり、エクスプローラでプロパティを開いたりすると)、
    サイズが 64 Byteになります。

    この状態で開けて見ると、アクセス情報(端末名と権限?)が書かれています。

    そういうものだったかも知れませんが...。

    また何かございましたらよろしくお願いします。

    キャンセル

  • Sitapper

    2020/02/06 20:47

    すみません。
    対象のディレクトリは DropBox や共有フォルダでなく、普通のものになります。

    キャンセル

回答 2

checkベストアンサー

0

接続 (OleDbConnection) の Close (Dispose も同じ) は Open で接続プールから取得した接続を接続プールに返すだけで、ldb を削除する訳ではなさそうです。

正常動作なので気にしないという話になると思うのですが。

それより気になるのは、例外が発生すると Close されない (接続プールに接続が戻されずリソースリークになる) ところ。using 句を使うことをお勧めします。

【追記】

下の 2020/02/07 10:36 の私のコメントで書いたことの証拠(?)画像を貼っておきます。

.accdb とのことなので .ldb ではなくて .laccdb になるはずですが、.ldb も .laccdb も見当たりませんでした。生成されているが即削除されるのかもしれませんが。

イメージ説明

ちなみに、その .accdb をダブルクリックして Access で開くと .laccdb ファイルが生成され、Access を閉じると即削除されます。

イメージ説明

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/02/14 16:00

    少し時間が取れたので、再度試験をしてみました。
    整理しますと、

    1. DELL Lattitude 5400 / RAM 8 GB に Windows10 Pro 64bit をクリーンインストール
    2. Office365 32bit版 をダウンロード導入
    Business Premium サブスクリプションがあります。
    64bit機に32bit版を導入した理由は、
    64bitだと別システムで弊害があるとかで指示によります。
    3. Accessを起動し新規で test.accdb を作成
    4. 添付のソースでテスト
    5. その結果...
    オープンで test.laccdb が現れるが、
    クローズでそれが消えるまでやはり 80 秒ほどかかり、
    その間 test.laccdb が排他的にロックされて他から編集できない。

    という状態が再現されました。
    前の質問では ldb が出来ていて、これは accdb の作成の仕方がまずかったかと推察しますが、
    今回は Access から作成したので laccdb になりました。

    接続プールというものを今回教えていただきましたので、
    オープン/クローズの瞬間に laccdb が作成/削除されるわけではないことは理解しましたが、
    それにしても時間がかかりすぎに思える次第です。

    YAmaGNZ さんに教えていただいたように接続文字列に
    OLE DB Services=-2
    を指定して接続プーリングを無効にするとこの現象は解消されました。
    だったらそれでいいのかというと、知識の浅さからちょっと判断しかねているといったところです。

    また再度質問を上げさせていただくかも知れません。

    今回はどうもありがとうございました。

    キャンセル

  • 2020/02/14 16:13 編集

    > だったらそれでいいのかというと、

    接続プールを無効にするわけですから、それではよくないと思います。自分が検証した時はそのような設定はしてませんけど、接続してデータ取得し Close でその直後にチェックしても .laccdb は見当たりませんでした。まだなんか変ですね。

    ちなみに、自分のサンプルの接続文字列は以下の通りです。

    Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\surfe\Documents\Visual Studio 2015\CsProject\WindowsFormsAccess\WindowsFormsAccess\Northwind2007.accdb

    キャンセル

  • 2020/02/14 16:27 編集

    あと、関係ないとは思うのですが、質問者さんのコードと自分のサンプルコードで違うところを書きますと、自分のコードでは Visual Studio のデータソース構成ウィザードで作った TableAbapter を利用しており、Open / Close は OreDbDataApapter の Fill メソッドが自動的に行っているところです。

    それで結果に差があるはずはないとは思いますが、念のためご連絡しておきます。

    キャンセル

0

接続プールにプールされ実際にCloseしきれていないというのは考えられないでしょうか?
OLE DB、ODBC、および Oracle 接続プール

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/02/10 15:26

    YAmaGNZさま

    アドバイスをありがとうございます。
    SurferOnWwwさまへの返答で書いたのですが、
    AccessRuntimeの導入順序によって、
    とりあえず現象が発生しなくなりました。
    まだ調べたい点もありますが、
    当面これで様子を見てみようとおもいます。

    ありがとうございました。

    キャンセル

  • 2020/02/14 09:29

    本件、少し先になりますが、引き続いて調査検証する予定です。
    YAmaGNZさまの接続文字列も試してみるつもりです。
    どうもありがとうございました。

    キャンセル

  • 2020/02/14 16:07

    思いがけず時間が取れましたので、教えてくださった接続文字列を試してみました。
    接続プーリングを無効にする設定だそうですね。
    結果、今回の現象は解消されました。
    オープン/クローズのタイミングで排他ファイルが作成/削除されるようです。

    ただ、前は確か Windows7 に Office2013 が入っていたと思うのですが、
    その際にはそのような指定がなくても今回のようにはならなかったので、
    少々モヤモヤはしています。

    またもう少し情報を集めて再度質問させていただくかもしれませんが、
    もう少し検証して問題無さそうであれば反映させてようと思います。

    どうもありがとうございました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.65%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる