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だけです。しかし、もっと経験のある人に確認したかったのです。ありがとう。