诊断SQLite锁定的原因 [英] Diagnosing cause of SQLite locking

查看:46
本文介绍了诊断SQLite锁定的原因的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 vb.net 应用程序中,我有一个案例,其中用户在表单的一部分中的操作正在创建一个 SQLite 锁,该锁会在应用程序后期导致问题(在这种情况下,将其关闭).

On a vb.net application, I have a case where a users actions in one portion of the form is creating a SQLite lock that causes problems later in the application (in this case, closing it down).

这是当用户将数据添加到要打印的项目列表时调用的子例程:

Here is the sub-routine called when users add data to a list of items to be printed:

Private Sub btnAdd_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAdd.Click
    ' Add item to printQueue => regenerate listPrint.items
    Dim queueItem As New Dictionary(Of String, String)
    queueItem("quantity") = inputQuantity.Value.ToString
    queueItem("description") = textDesc.Text
    queueItem("sizeUK") = inputSize.Value.ToString.Replace(".5", "½").Replace(".0", "")
    queueItem("sku") = listStyles.SelectedItem.ToString
    queueItem("colour") = textColour.Text
    queueItem("date") = textDateCode.Text
    queueItem("name") = textName.Text

    Try
        queueItem("sizeEU") = sizeEU(inputSize.Value).ToString.Replace(".5", "½")
    Catch ex As Exception
        queueItem("sizeEU") = "??"
    End Try

    ' US Size: M = UK + 1; F = UK + 1.5
    queueItem("sizeUS") = (inputSize.Value + 1.5 - (chkSex.CheckState * 0.5)).ToString.Replace(".5", "½")

    ' Add the image data as a string
    dbLocalQuery = New SQLiteCommand("SELECT * FROM tblImages WHERE id ='" & listStyles.SelectedItem.ToString & "'", dbLocal)

    If dbLocal.State = ConnectionState.Closed Then
        dbLocal.Open()
    End If

    Dim r As SQLiteDataReader = dbLocalQuery.ExecuteReader()

    Try
        r.Read()
        queueItem("image") = byte2string((r("image")))
    Catch ex As Exception
        queueItem("image") = settings("imgNotFound")
    Finally
        If dbLocal.State = ConnectionState.Open Then
            dbLocal.Close()
        End If
    End Try

    printQueue.Add(printQueue.Count + 1, queueItem)
    MsgFrame.Items.Add(printQueue(printQueue.Count)("sku") & " x" & printQueue(printQueue.Count)("quantity"))
    MsgFrame.SelectedIndex = MsgFrame.Items.Count - 1
    ' Update print queue list
    populateList()
End Sub

查询涉及的数据库中唯一的表是 tblImages.即便如此,连接一旦完成就会关闭.

The only table in the database touched by the query is tblImages. Even then, the connection is closed once finished.

关闭表单时,会调用一个函数,该函数在加载时捕获写入到名为 Settings 的 Dictionary 中的数据,并将其重新插入到数据库中.

When closing the form down, a function is called that captures data that is written to the Dictionary called Settings on load and reinserts it into the database.

Public Function dbLocalSave() As Boolean
    'Recreates the tblSettings from current values stored in settings 
    Try
        If dbLocal.State = ConnectionState.Closed Then
            dbLocal.Open()
        End If

        If dbLocal.State = ConnectionState.Open Then
            MsgFrame.Items.Add("Flushing local settings table")
            MsgFrame.SelectedIndex = MsgFrame.Items.Count - 1

            For Each pair In settings
                Debug.Print("+ tblSettings: " & pair.Key & " = " & pair.Value)

                dbLocalQuery = New SQLiteCommand("DELETE FROM tblSettings where name = '" & pair.Key & "';", dbLocal)
                dbLocalQuery.ExecuteNonQuery()

                dbLocalQuery = New SQLiteCommand("INSERT INTO tblSettings (`name`,`value`) VALUES ('" & pair.Key & "','" & pair.Value & "');", dbLocal)
                dbLocalQuery.ExecuteNonQuery()
            Next
            Return True
        Else
            Return False
        End If
    Catch sqlex As SQLiteException
        MessageBox.Show(sqlex.Message, "SQL Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
    Catch ex As Exception
        MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
    Finally
        If dbLocal.State = ConnectionState.Open Then
            dbLocal.Close()
        End If
    End Try

End Function

此函数在 dbLocalQuery.ExecuteNonQuery() 阶段立即失败并出现数据库锁定错误,但我不明白为什么.我没有正确处理我的数据库关闭吗?我的印象是 SQLite 只在写入时创建锁,这在所描述的显式情况下从未发生过.

This Function immediately fails at the dbLocalQuery.ExecuteNonQuery() stage with a db lock error, but I cannot understand why. Am I not handling my db closing correctly? I was under the impression that SQLite only created locks on writes, which never happens in the explicit case described.

如果我不向打印队列添加"一个项目(程序的基本功能),程序会正常关闭.

If I do not 'Add' an item to the print queue (fundamental functionality of the program), the program closes gracefully.

推荐答案

dispose每个命令执行后应该可以解决问题

Dispose each command after executing should solve the problem

dbLocalQuery.ExecuteNonQuery()
dbLocalQuery.Dispose()

问题是因为您同时执行了删除和插入命令,这导致了错误

the problem is because you have delete and insert command concurrently executing which is causing the error

            dbLocalQuery = New SQLiteCommand("DELETE FROM tblSettings where name  = '" & pair.Key & "';", dbLocal)
            dbLocalQuery.ExecuteNonQuery()
            'insert here '
            dbLocalQuery.dispose()
            dbLocalQuery = New SQLiteCommand("INSERT INTO tblSettings (`name`,`value`) VALUES ('" & pair.Key & "','" & pair.Value & "');", dbLocal)
            dbLocalQuery.ExecuteNonQuery()
            'here also '
            dbLocalQuery.dispose()

参考:http://www.sqlite.org/cvstrac/wiki?p=DatabaseIsLocked

这篇关于诊断SQLite锁定的原因的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆