SQLite数据库锁定问题

时间:2015-05-05 01:41:43

标签: c# database sqlite locking

我在这个网站上阅读了很多关于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;
    }
}

0 个答案:

没有答案