1

私のプログラムは、独自の更新機能を実行して sqlite データベースをチェックし、変更が見つかった場合に更新する多くのクラスで構成されています。

Async Function update() As Task(Of String)
.
.
  Await Task.Run(Sub()
    .
    .                          
  End Sub)
.
.
  helper.updatedb(par1, par2, par3, par4)
.
.
End Function

Sub updatedb(ByVal name As String, ByVal entry As String, ByVal smth As String, Optional ByVal random As String = vbNullString)

            Dim SQLconnect As New SQLite.SQLiteConnection()
            Dim SQLcommand As SQLiteCommand
            SQLconnect.ConnectionString = "data source=" + dbpath
            SQLconnect.Open()
            SQLcommand = SQLconnect.CreateCommand
            SQLcommand.CommandText = "SELECT ""entry"" FROM profiles WHERE ""name"" = @name"
            SQLcommand.Parameters.AddWithValue("@name", LCase(name))
            Dim SQLreader As SQLiteDataReader = SQLcommand.ExecuteReader()
            SQLreader.Read()

            Dim result As String = SQLreader(0)

                SQLcommand.Dispose()
                SQLcommand = SQLconnect.CreateCommand
                SQLcommand.CommandText = "UPDATE profiles SET ""entry"" = @entry WHERE ""name"" = @name"
                SQLcommand.Parameters.AddWithValue("@name", LCase(name))
                SQLcommand.Parameters.AddWithValue("@entry", entry)

                SQLcommand.ExecuteNonQuery()

            SQLcommand.Dispose()
            SQLreader.Close()
            SQLconnect.Close()
            SQLconnect.Dispose()
    End Sub

別のスレッドがデータベースへの書き込みアクセス権を持っている可能性があるときに SQLcommand.ExecuteNonQuery が実行されると、問題が発生します。「タイプ 'System.Data.SQLite.SQLiteException' の初回例外が System.Data.SQLite.dll で発生しました」.

更新コマンドでミューテックスを使用してこれに対抗できることを他のスレッドで読みました。コードにミューテックスを実装するにはどうすればよいですか? 移植性を優先し、そのような同時実行性の問題がない sqlite の代替手段はありますか?

4

2 に答える 2

0

まあ、私はのろわれます...問題はdisposeステートメントの配置にあったようです:

Dim SQLreader As SQLiteDataReader = SQLcommand.ExecuteReader()
->SQLcommand.Dispose()
SQLreader.Read()

Dim result As String = SQLreader(0)
->SQLreader.Close()

今では意図したとおりに動作します...

于 2013-09-06T20:10:54.903 に答える
0

次のオンライン ヘルプを参照してください。

ロック変数を作成してからロックします。一度にロックできるスレッドは 1 つだけで、他のスレッドは自動的に待機します。

Dim lockThis As New Object

Sub updatedb(ByVal name As String, ...)
    SyncLock lockThis
        Dim SQLconnect As New SQLite.SQLiteConnection()
        ...
    End SyncLock
End Sub
于 2013-09-05T10:50:44.090 に答える