我们在版本1.0.80中使用System.Data.SQLite Wrapper。使用它来建立与单个SQLite数据库的多个连接将显示一种奇怪的行为。
我们确保只有一个可写连接和多个只读连接。
当第一个建立的连接是只读连接时(使用连接字符串参数Read Only = true),第二个连接(由于缺少只读参数而可写)不会保持更改。也没有抛出异常。 如果我们转过来,所以我们先建立写访问权限和以后的只读连接,持久化更改不是问题。
问题是,在我们的代码中,我们无法确保首先使用与SQLite数据库文件的哪个连接,并且使用多个写连接会导致死锁情况。
有人知道这个错误吗?有可用的解决方法吗?
一些源代码:
private static void Test() {
string fileFullPath = "\\Flash\\test.db";
IDbConnection readCon = new SQLiteConnection(@"Data Source=" + fileFullPath + ";Read Only=true");
readCon.Open();
using (IDbCommand cmd = readCon.CreateCommand())
{
cmd.CommandText = "PRAGMA synchronous=OFF";
cmd.ExecuteNonQuery();
}
using (IDbCommand cmd = readCon.CreateCommand())
{
cmd.CommandText = "PRAGMA journal_mode=OFF";
cmd.ExecuteNonQuery();
}
using (IDbCommand cmd = readCon.CreateCommand())
{
cmd.CommandText = "SELECT * FROM tbltest WHERE foo = 'bar'";
Console.WriteLine(cmd.ExecuteReader().Read());// FALSE as expected
}
// readcon still open
// open a writable connection
IDbConnection con = new SQLiteConnection(@"Data Source=" + fileFullPath);
con.Open();
using (IDbCommand cmd = con.CreateCommand())
{
cmd.CommandText = "PRAGMA synchronous=OFF";
cmd.ExecuteNonQuery();
}
using (IDbCommand cmd = con.CreateCommand())
{
cmd.CommandText = "PRAGMA journal_mode=OFF";
cmd.ExecuteNonQuery();
}
IDbTransaction transaction = con.BeginTransaction();
using (IDbCommand cmd = con.CreateCommand())
{
cmd.CommandText = "INSERT INTO tbltest(foo) values('bar')";
cmd.ExecuteNonQuery();
}
transaction.Commit();// persisting occurs here
using (IDbCommand cmd = readCon.CreateCommand())
{
cmd.CommandText = "SELECT * FROM tbltest WHERE foo = 'bar'";
Console.WriteLine(cmd.ExecuteReader().Read());// TRUE as expected
}
con.Close();
readCon.Close();
// verify writing
readCon = new SQLiteConnection(@"Data Source=" + fileFullPath + ";Read Only=true");
readCon.Open();
using (IDbCommand cmd = readCon.CreateCommand())
{
cmd.CommandText = "SELECT * FROM tbltest WHERE foo = 'bar'";
Console.WriteLine(cmd.ExecuteReader().Read()); // TRUE expected but we get FALSE
}
readCon.Close();
}
输出:
FALSE
TRUE
FALSE
感谢您的帮助, schibbl