1

postgresql で SELECT と SELECT FOR UPDATE の違いをテストしています。SELECT ステートメントで気づいたことの 1 つは、ロックまたは競合が発生すると、postgresql が静かに停止しているように見えることです。次のスクリプトを検討してください。

require("luasql.postgres")

-- GLOBAL DECLARES --
local con
local env
local databasename = "XXXX"
local databaseUser = "XXXX"
local databasepassword = "XXXX"
local databaseserver="xx.xx.xx.xx" 
local databaseport = 5432 

local databaseconnect = function()
   if not con then
      -- create environment object   
      env = assert (luasql.postgres())
      con = assert (env:connect(databasename, databaseUser, databasepassword, databaseserver))   
      return true
   else
      return false 
   end
end

local escape = function(sql)
     sql = sql or ""
     return con:escape(sql)
end

local databasedisconnect = function()
   if env then
      env:close()
      env = nil
   end
   if con then
      con:close()
      con = nil
   end
end

local userid, servername = ...

--CONNECT TO DATABASE
if not con then databaseconnect() end

print(now)
sql = "UPDATE tbl_availablenumbers SET UsedYesNo = true, user_id="..userid..", updateddatetime='"..os.date("%Y-%m-%d %H:%M:%S").."' WHERE reservationnumber =("
      .."SELECT reservationnumber FROM tbl_availablenumbers WHERE UsedYesNo=false Order By id ASC Limit 1 ) RETURNING reservationnumber"

print('Attempting to update tbl_availablenumbers table...')
assert(con:execute(sql))       

--DISCONNECT FROM DATABASE
if con then databasedisconnect() end
print("Goodbye")

更新が機能しない何らかの障害が発生した場合、postgresql はメッセージを返すと想定していました。

これが私がやっていることです。上記のロジックを X 回呼び出すラッパー スクリプトを作成しました。とりあえず100回やってみます。次に、これらのスクリプトを 2 つの異なるサーバーから同じデータベースに対して実行します。両方のステートメントを実行した後、合計 200 件のレコードがないため、失敗/ロックの問題があることはわかっています。セッション 1 では、たとえば 99 が作成され、その他は 65 が作成されます。私の質問は、ドロップされたトランザクションが通知されないのはなぜですか? NOWAIT 句について何か読みました。それはそれと何か関係がありますか?私はまだ postgresql にあまり詳しくなく、競合状態で待機する時間を定義する構成設定がある mysql や ms sql サーバーなどの他のデータベースと比較してきました。

おそらく、必要なのはNOWAITだけです。しかし、もっと経験のある人に確認したかったのです。ありがとう。

4

0 に答える 0