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
The only table in the database touched by the query is tblImages. Even then, the connection is closed once finished.
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
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.