我在这个网站上阅读了很多关于SQLite数据库锁的帖子,但我仍然找不到我的情况的原因。
我正在尝试在插入之前检查表中是否有记录。 我尝试插入时得到数据库锁。 (它有时不会在第一次发生时发生,我也不明白为什么。)
这是我的代码。
private void bt_save_Click(object sender, EventArgs e)
{
if (!SaveValidation()) // <--- I am checking for duplication
{
DialogResult = DialogResult.None;
return;
}
int result = Schedule.addSchedule( // <--- I am inserting
medicNumber,
dtp_date.Value,
Int16.Parse(cb_hour.Text),
Int16.Parse(cb_minute.Text),
Int16.Parse(cb_duration.Text),
tb_patient.Text,
tb_memo.Text);
if (result > 0)
{
MessageBox.Show("Saved succesfully.");
}
else
{
MessageBox.Show("Failed to save.");
DialogResult = DialogResult.None;
}
}
private bool SaveValidation()
{
DateTime now = DateTime.Now;
DateTime appointment;
appointment = dtp_date.Value;
appointment = appointment.AddHours(Int16.Parse(cb_hour.Text));
appointment = appointment.AddMinutes(Int16.Parse(cb_minute.Text) + 1);
if (now > appointment)
{
MessageBox.Show("Cannot make appointment in the past." + appointment.ToString());
cb_hour.Focus();
return false;
}
if (tb_patient.TextLength == 0)
{
MessageBox.Show("Patient name is missing.");
tb_patient.Focus();
return false;
}
if (!Schedule.IsScheduleAvailable(medicNumber, dtp_date.Value.Date, Int16.Parse(cb_hour.Text),
Int16.Parse(cb_minute.Text), Int16.Parse(cb_duration.Text)))
{
MessageBox.Show("Already booked schedule exists at that time.");
cb_hour.Focus();
return false;
}
return true;
}
以下是Schedule
的数据模型类static class Schedule
{
private static SQLiteConnection DbConnection()
{
SQLiteConnectionStringBuilder builder = new SQLiteConnectionStringBuilder();
builder.DataSource = "database.sqlite";
SQLiteConnection conn = new SQLiteConnection(builder.ToString());
conn.Open();
return conn;
}
public static bool IsScheduleAvailable(int medicNo, DateTime value_date, int hour, int minute, int duration)
{
bool returnValue = false;
using (SQLiteConnection conn = DbConnection())
{
string query = "select * from tb_schedule where medicNo = @medicNo and"
+ " ( datetime(@value_date, '+'||@hour||' hour', '+'||@minute||' minute') between "
+ "datetime(value_date, '+'||hour||' hour', '+'||minute||' minute') and "
+ "datetime(value_date, '+'||hour||' hour', '+'||minute||' minute', '+'||duration||' minute')"
+ " or datetime(@value_date, '+'||@hour||' hour', '+'||@minute||' minute', '+'||@duration||' minute') between "
+ "datetime(value_date, '+'||hour||' hour', '+'||minute||' minute') and "
+ "datetime(value_date, '+'||hour||' hour', '+'||minute||' minute', '+'||duration||' minute') )";
using (SQLiteCommand cmd = new SQLiteCommand(query, conn))
{
SQLiteParameter parm0 = new SQLiteParameter("@medicNo", DbType.Int16);
SQLiteParameter parm1 = new SQLiteParameter("@value_date", DbType.DateTime);
SQLiteParameter parm2 = new SQLiteParameter("@hour", DbType.Int16);
SQLiteParameter parm3 = new SQLiteParameter("@minute", DbType.Int16);
SQLiteParameter parm4 = new SQLiteParameter("@value_date", DbType.DateTime);
SQLiteParameter parm5 = new SQLiteParameter("@hour", DbType.Int16);
SQLiteParameter parm6 = new SQLiteParameter("@minute", DbType.Int16);
SQLiteParameter parm7 = new SQLiteParameter("@duration", DbType.Int16);
parm0.Value = medicNo;
parm1.Value = value_date;
parm2.Value = hour;
parm3.Value = minute;
parm4.Value = value_date;
parm5.Value = hour;
parm6.Value = minute;
parm7.Value = duration;
cmd.Parameters.Add(parm0);
cmd.Parameters.Add(parm1);
cmd.Parameters.Add(parm2);
cmd.Parameters.Add(parm3);
cmd.Parameters.Add(parm4);
cmd.Parameters.Add(parm5);
cmd.Parameters.Add(parm6);
cmd.Parameters.Add(parm7);
using (SQLiteDataReader reader = cmd.ExecuteReader())
{
if (reader.HasRows)
{
returnValue = false;
}
else
{
returnValue = true;
}
reader.Close();
}
cmd.Dispose();
}
conn.Close();
}
//SQLiteConnection.ClearAllPools();
GC.Collect();
return returnValue;
}
public static int addSchedule(int medicNo, DateTime value_date, int hour, int minute, int duration, string patient, string memo)
{
string query = "insert into tb_schedule ( medicNo, value_date, hour, minute, duration, patient, memo )"
+ "values ( @medicNo, @value_date, @hour, @minute, @duration, @patient, @memo )";
SQLiteConnection conn = DbConnection();
SQLiteCommand cmd = new SQLiteCommand(query, conn);
SQLiteParameter parm0 = new SQLiteParameter("@medicNo", DbType.Int16);
SQLiteParameter parm1 = new SQLiteParameter("@value_date", DbType.DateTime);
SQLiteParameter parm2 = new SQLiteParameter("@hour", DbType.Int16);
SQLiteParameter parm3 = new SQLiteParameter("@minute", DbType.Int16);
SQLiteParameter parm4 = new SQLiteParameter("@duration", DbType.Int16);
SQLiteParameter parm5 = new SQLiteParameter("@patient", DbType.String);
SQLiteParameter parm6 = new SQLiteParameter("@memo", DbType.String);
parm0.Value = medicNo;
parm1.Value = value_date.Date;
parm2.Value = hour;
parm3.Value = minute;
parm4.Value = duration;
parm5.Value = patient;
parm6.Value = memo;
cmd.Parameters.Add(parm0);
cmd.Parameters.Add(parm1);
cmd.Parameters.Add(parm2);
cmd.Parameters.Add(parm3);
cmd.Parameters.Add(parm4);
cmd.Parameters.Add(parm5);
cmd.Parameters.Add(parm6);
int result = 0;
try
{
using (SQLiteTransaction transaction = conn.BeginTransaction())
{
using (cmd)
{
result = cmd.ExecuteNonQuery();
}
transaction.Commit(); // <--- This is where I get the database lock error
}
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
conn.Close();
cmd.Dispose();
SQLiteConnection.ClearAllPools();
GC.Collect();
return result;
}
}