我想这样做:的SQLite一直这样做SELECT + UPDATE时锁定我的数据库(C#)
- 阅读从一个SQLite数据库行(在GetRuleByID()方法)
- 更新同一行我在刚才读(1)(见UpdateStatusForRuleID()方法)
但我的问题是,SQLite的在SELECT中GetRuleByID(后锁定数据库中),所以当所谓的在UpdateStatusForRuleID()的更新是唯一成功第一次。
我已经尝试启用SQLite以及PRAGMA read_uncommitted = 1日志记录以避免SQLite锁定数据库的SELECT,但这似乎不工作。
这应该很简单,但我到目前为止花了整整一个晚上试图解决这个问题...请帮助!
private static MicroRuleEngine.Rule GetRuleByID(int ruleID, SQLiteConnection connection, out Dictionary<string, string> dict)
{
dict = new Dictionary<string, string>();
string sql = String.Format("select * from rules WHERE ID = {0} ", ruleID.ToString());
SQLiteCommand command = new SQLiteCommand(sql, connection);
SQLiteDataReader reader = command.ExecuteReader();
if (reader.HasRows)
{
reader.Read();
// Convert row into a dictionary
for (int lp = 0; lp < reader.FieldCount; lp++)
{
dict.Add(reader.GetName(lp), reader.GetValue(lp) as string);
}
string json = dict["fulljson"];
MicroRuleEngine.Rule r = Newtonsoft.Json.JsonConvert.DeserializeObject<MicroRuleEngine.Rule>(json);
//command.Dispose();
return r;
}
}
internal static void UpdateStatusForRuleID(SQLConnectionManager DBMANAGER, int ruleID, bool status)
{
Dictionary<string, string> dict = null;
string dbVal = (status) ? "1" : "0";
MicroRuleEngine.Rule r = null;
string newJSON = null;
using (SQLiteConnection connection = DBMANAGER.CreateConnection())
{
r = GetRuleByID(ruleID, connection, out dict);
r.Active = (status);
newJSON = Newtonsoft.Json.JsonConvert.SerializeObject(r);
Thread.Sleep(1000);
string sql = "UPDATE rules SET active = @a, [email protected] WHERE ID = @i";
using (var command = new SQLiteCommand(sql, connection))
{
command.Parameters.Add(new SQLiteParameter("@a", dbVal));
command.Parameters.Add(new SQLiteParameter("@i", ruleID));
command.Parameters.Add(new SQLiteParameter("@j", newJSON));
command.ExecuteNonQuery(); // Database is locked here ???
}
connection.Close();
}
}
1.从上面的代码我没有看到两种方法之间的关系2.你是什么意思的'锁',以及如何确定是否锁定? –
第一部分为命令对象创建一个using块。在第二部分中,connection.Close();可以留下,因为你实现了use-block和.Close();内部只需调用.Dispose();这是由你的使用块完成的。进一步说,你有什么理由使用Thread.Sleep(1000); ??? – Sebi
那么调用代码调用UpdateStatusForRuleID(),然后在执行实际的UPDATE命令之前调用GetRuleByID()。 –