C# SQLite在执行SELECT+UPDATE(C)时一直锁定我的数据库
我正在尝试这样做: 在GetRuleByID方法中从SQLite数据库读取一行 更新我刚才在1中读取的同一行,请参见UpdateStatusForRuleID方法 但是,我的问题是SQLite会在GetRuleByID中选择后锁定数据库,这样UpdateStatusForRuleID中的更新只有在第一次调用时才会成功 为了避免SQLite为SELECT锁定数据库,我尝试在SQLite中启用写前日志记录以及PRAGMA read_uncommitted=1,但这似乎不起作用 这应该很简单,但到目前为止,我已经花了整整一个晚上试图解决这个问题。。。请帮忙C# SQLite在执行SELECT+UPDATE(C)时一直锁定我的数据库,c#,sqlite,sql-update,locking,C#,Sqlite,Sql Update,Locking,我正在尝试这样做: 在GetRuleByID方法中从SQLite数据库读取一行 更新我刚才在1中读取的同一行,请参见UpdateStatusForRuleID方法 但是,我的问题是SQLite会在GetRuleByID中选择后锁定数据库,这样UpdateStatusForRuleID中的更新只有在第一次调用时才会成功 为了避免SQLite为SELECT锁定数据库,我尝试在SQLite中启用写前日志记录以及PRAGMA read_uncommitted=1,但这似乎不起作用 这应该很简单,但到目前
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;
}
}
}数据库被锁定意味着同一进程或其他进程中的其他连接仍有活动事务 除非使用多个线程,否则不需要多个连接;对所有数据库访问只使用一个连接对象 如果您决定使用临时对象和连接,请确保所有命令、读取器和事务对象和连接都已正确清理,方法是使用:
显然,下面的代码是有效的。我基本上放弃了GetRuleByID方法,但后来我不得不重新编写其他4个方法 感谢所有提供意见的人
internal static void UpdateStatusForRuleID(SQLConnectionManager DBMANAGER, int ruleID, bool status)
{
string dbVal = (status) ? "1" : "0";
MicroRuleEngine.Rule r = null;
string newJSON = null;
using (SQLiteConnection conn = DBMANAGER.CreateConnection())
{
string sql = String.Format("select * from rules WHERE ID = {0} ", ruleID.ToString());
using (var command = new SQLiteCommand(sql, conn))
using (var reader = command.ExecuteReader())
{
if (reader.HasRows)
{
reader.Read();
string json = reader["fulljson"].ToString();
r = Newtonsoft.Json.JsonConvert.DeserializeObject<MicroRuleEngine.Rule>(json);
r.Active = (status);
newJSON = Newtonsoft.Json.JsonConvert.SerializeObject(r);
string sql2 = "UPDATE rules SET active = @a, fulljson=@j WHERE ID = @i";
using (var command2 = new SQLiteCommand(sql2, conn))
{
command2.Parameters.Add(new SQLiteParameter("@a", dbVal));
command2.Parameters.Add(new SQLiteParameter("@i", ruleID));
command2.Parameters.Add(new SQLiteParameter("@j", newJSON));
command2.ExecuteNonQuery();
}
}
}
}
}
1.从上面的代码中,我没有看到两个方法2之间的关系。“锁定”是什么意思?如何确定是否锁定?在第一部分,为您的命令对象创建一个使用块。第二部分是连接。关闭;可以向左,因为您使用block和.Close实现;内部只需打电话。处理;这是通过使用块完成的。此外,您使用Thread.Sleep1000;还有什么原因吗;???调用代码调用UpdateStatusForRuleID,然后在执行实际的更新命令之前调用GetRuleByID。@sabi执行Thread.Sleep的原因是UpdateStatusForRuleID仅在第一次调用时成功,并且对于GetRuleByID似乎要创建的SQLite读锁和Thread.Sleep只是一种方法尝试等待锁被释放…@HenrikSkov在调用代码时是否使用多线程?
using (var command = new SQLiteCommand(sql, connection))
using (var reader = command.ExecuteReader())
{
if (reader.HasRows)
...
}
internal static void UpdateStatusForRuleID(SQLConnectionManager DBMANAGER, int ruleID, bool status)
{
string dbVal = (status) ? "1" : "0";
MicroRuleEngine.Rule r = null;
string newJSON = null;
using (SQLiteConnection conn = DBMANAGER.CreateConnection())
{
string sql = String.Format("select * from rules WHERE ID = {0} ", ruleID.ToString());
using (var command = new SQLiteCommand(sql, conn))
using (var reader = command.ExecuteReader())
{
if (reader.HasRows)
{
reader.Read();
string json = reader["fulljson"].ToString();
r = Newtonsoft.Json.JsonConvert.DeserializeObject<MicroRuleEngine.Rule>(json);
r.Active = (status);
newJSON = Newtonsoft.Json.JsonConvert.SerializeObject(r);
string sql2 = "UPDATE rules SET active = @a, fulljson=@j WHERE ID = @i";
using (var command2 = new SQLiteCommand(sql2, conn))
{
command2.Parameters.Add(new SQLiteParameter("@a", dbVal));
command2.Parameters.Add(new SQLiteParameter("@i", ruleID));
command2.Parameters.Add(new SQLiteParameter("@j", newJSON));
command2.ExecuteNonQuery();
}
}
}
}
}