Mono.Data.Sqlite
パッケージに含まれているMono実装を使用してSQLiteデータベースに書き込むための単純なMonoC#アプリケーションを作成しました。
using System;
using Mono.Data.Sqlite;
class MainClass
{
public static void Main (string[] args)
{
using (var dbConnection = new SqliteConnection (@"Data Source=/var/log/gmblog;Version=3;"))
{
dbConnection.Open();
string sql = @"INSERT INTO ""queue"" (""data"") VALUES(""Test"")";
using (var insertCommand = new SqliteCommand (sql, dbConnection))
{
insertCommand.ExecuteNonQuery();
}
}
}
}
これは、次のような別のアプリケーションから挿入を実行し、sqlite3
このアプリケーションを実行し続けるまでは正常に機能します。
sqlite> insert into queue ("data") VALUES("test2");
これで、C#プログラムは、次のエラーが発生するまでハングします。
Unhandled Exception: Mono.Data.Sqlite.SqliteException: The database file is locked
sqlite3
作成したC++アプリケーションの他のインスタンスまたはC++アプリケーションからテーブルに書き込むのに問題はありません。
インスタンスを閉じるとsqlite3
、C#アプリケーションが再び機能します。
INSERTを実行した後、リーダーロックを取得したlsof /var/log/gmblog
ショーを実行します。sqlite3
sqlite3 15578 cup 3ur REG 8,17 13312 4988505 /var/log/gmblog
INSERTの前は、このロックはありませんでした。
sqlite3 15578 cup 3u REG 8,17 13312 4988505 /var/log/gmblog
しかし、私が指摘したように、他のアプリケーションがデータベースを使用している間、他のアプリケーションはテーブルに書き込まれる問題はありません。
私のC#コードの何が問題になっているのかについてのアイデアはありますか?SQLiteのMono実装のバグですか?
更新25/11
dbConnection.Open();
これがデータベースロックエラーの原因であり、ではないことに注意してくださいinsertCommand.ExecuteNonQuery();
。つまり、次のコードも機能しません。
using System;
using Mono.Data.Sqlite;
class MainClass
{
public static void Main (string[] args)
{
using (var dbConnection = new SqliteConnection (@"Data Source=/var/log/gmblog;Version=3;"))
{
dbConnection.Open();
}
}
}