【发布时间】:2012-11-26 19:58:37
【问题描述】:
我编写了一个简单的 Mono C# 应用程序,用于使用 Mono.Data.Sqlite 包中的 Mono 实现写入 SQLite 数据库:
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++ 应用程序写入表没有任何问题。
如果我关闭 sqlite3 实例,那么 C# 应用程序将再次运行。
执行lsof /var/log/gmblog 表明sqlite3 在执行INSERT 后获得了读者锁:
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();。 IE。以下代码也不起作用:
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();
}
}
}
【问题讨论】:
-
如果您执行“提交事务”会发生什么;在插入后的sqlite3中? sqlite3 中的未完成锁定将阻止您的应用。
-
我在尝试提交时收到以下错误:
sqlite> commit transaction; Error: cannot commit - no transaction is active -
我很确定问题不是活动事务,因为其他 sqlite3 实例能够进行写入就好了。