1

ユーザーに属するウィジェットを削除する機能を提供する Web アプリがあります。削除を行うための現在のロジックは次のようになります。

local delete_widget = function(widgetid, user)
   local retval = ""      

         sql = "DELETE FROM widgets Where widgetid="..widgetid
         cur, err = assert(con:execute(sql))
         if not err then
               sql = "SELECT * FROM widgets where widgetid = ".. widgetid
               listofwidgets = executesqlandreturntable(sql)
               if #listofwidgets == 0 then
                    retval = "Deleted widget"
               else
                    retval = "Unable to delete widget"
               end
         else
               retval = "unable to delete widget"
         end 
   return retval
end

私が疑問に思っているのは、これをトランザクションに変更する必要があるかどうかです。現在、削除の試みが何らかの理由で失敗した場合、私は何もしていません。まだ存在するかどうかを確認するために選択を行い、存在する場合はエラーをスローします。

select ステートメントがウィジェットがまだ存在することを検出した場合、delete sql ステートメントをロールバックするように、完全な begin transaction/commit/rollback を実行する必要があるかどうか疑問に思っています。

しかし、次の質問があります。

  1. pgadmin3 を使用して、現在のトランザクション分離レベルの値を確認するにはどうすればよいですか?

  2. デフォルトのままにしておくと (私が読んだ内容によると「read commit」)、delete コマンドと select コマンドの両方が終了している間、widgets テーブルがロックされますよね? これは、このトランザクションが完了するまで、誰もウィジェット テーブルから選択できないことを意味しますよね? 何百人ものユーザーがいることを考えると、それは良いことではないように思えます。

コメント/提案をいただければ幸いです。

4

1 に答える 1

1
  1. わからない。
  2. 最新のデータベースでは、必ずしもテーブル全体をロックすることなく、行レベルでロックを取得できますが、これは非常に非効率的です。したがって、この場合、トランザクションが完了するまで行レベルのロックのみが取得されます。つまり、他のユーザーはテーブルから選択できますが、トランザクションによってロックされていない行のみを選択できます。

行を削除した後に別の選択を発行する理由がわかりません。削除が成功するか、クエリがエラーを返します (たとえば、ロック タイムアウトが原因で)。再度確認する必要はありません。

したがって、この場合、DELETE はその行の書き込みロックを暗黙的に取得するため、トランザクションを開始する必要はありません。自動コミットがオフになっていない限り、とにかくコミットする必要があります。

于 2013-04-25T18:30:04.400 に答える