あなたには、あなたが持っていると思われる問題があることは明らかです。
テーブルの行を更新すると、本来、その行に行レベルのロックが設定されます。コミットまたはロールバックによってトランザクションを終了してロックを解除するまで、他のセッションはその行を更新できません。トランザクションを完了すると、他のセッションで更新プログラムを上書きすることができます。 SELECT
の行をロックする必要はありません。
更新が失われないようにアプリケーションを作成しようとしている場合(つまり、更新されたデータを最初に他のユーザーに表示せずにトランザクションをコミットした後に行ったのと同じ行を別のセッションで更新しないようにしたい場合)何らかの追加のロックを実装する必要があります。最も効率的なのは、表のなんらかのLAST_UPDATE_TIMESTAMP
列を使用してオプティミスティック・ロックを実装することです。テーブルにこの列を追加していない場合は、ユーザーに提示するデータを照会するたびにLAST_UPDATE_TIMESTAMP
を選択し、UPDATE
にはLAST_UPDATE_TIMESTAMP
を指定します。 UPDATE
が正確に1行更新された場合、クエリを実行してから誰もデータを変更していないことがわかります。 UPDATE
が0行更新された場合、クエリを実行してからデータが変更されたことがわかり、アプリケーションは適切な処置(つまり、データの再クエリ、ユーザーへの再提示、彼らが行ったコミットされていない変更のいずれかを維持するなど)。
クエリには別の問題があります。 SELECT
のステートメントは、あなたが思うような(または意図する)ことはほとんどありません。このクエリは、MYTABLE
から任意の10行を取得します。ここで、PROCS_DT
はNULLで、これらの任意の10行を並べ替えます。
SELECT
id
FROM mytable
WHERE
rownum<=10 and PROCS_DT is null
order by CRET_DT,PRTY desc
あなたが実際に「トップ10」の結果を取得したいと仮定すると、あなたはすなわち、ROWNUM
述語を適用する前に、サブクエリで
SELECT
id
FROM (SELECT *
FROM mytable
WHERE procs_dt IS NULL
ORDER BY cret_dt, prty desc)
WHERE
rownum<=10
をORDER BY
を行う必要がありますまたはあなたが使用することができますすなわち、
SELECT
id
FROM (SELECT m.*,
rank() over (ORDER BY cret_dt, prty desc) rnk
FROM mytable m
WHERE procs_dt IS NULL)
WHERE
rnk<=10
"最もORA_ROWSCN疑似列を使用してオプティミスティック・ロックを実装することが効率的です。オプティミスティック・ロックのためにORA_ROWSCNを使用することには問題があるようです。 OPの質問のクエリが壊れていることを指摘するため、http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:2680538100346782134#2680546500346035086 –
+1を参照してください。 –
真。私の質問で問題を指摘していただきありがとうございます。私のスタックオーバーフローに対する以前の答えの一部として、私はあなたが私に与えた正確なクエリを実際に得ました。しかし、それは私の最後からタイプミスです。 – Shiv