我想這樣做:的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()。 –