0

次のコードを使用してSybaseにプロシージャがあります。

begin transaction get_virtual_acc

    UPDATE store_virtual_acc SET isProc = 1, Uid = @uid, DateReserv = getdate()  
    from store_virtual_acc (index idx_id) WHERE id = (SELECT min(id) FROM store_virtual_acc (index idx_uid) where  Uid = null and isProc = null)  

commit transaction get_virtual_acc 

問題は、プロシージャが複数のユーザーに同時に呼び出されると、同じ min(id) を受け取り、テーブル内の同じ行を異なる値 @uid で更新できることです。その結果、データが歪んでしまいます。行が単一のユーザーを更新するために既に選択されている場合、他のユーザーはそれを選択できないという結果を達成する必要があります。テーブルにはロック タイプのデータ行があります。

次のようにトランザクション レベルのロックを使用しようとしましたが、トランザクションの開始前にトランザクション分離レベル 3 を設定しましたが、プロシージャを呼び出すアプリケーションで例外 java.sql.SQLException: サーバー コマンド (ファミリ ID # 0、プロセス ID # 530) がデッドロックに遭遇しました状況。コマンドを再実行してください。

どんな助けにも感謝します。

4

1 に答える 1

1

次のようなことを試してください:

begin transaction get_virtual_acc

UPDATE store_virtual_acc SET isProc = 1, Uid = @uid, DateReserv = getdate()  
from store_virtual_acc (index idx_id) WHERE id = (SELECT min(id) FROM store_virtual_acc (index idx_uid) holdlock where  Uid = null and isProc = null )  

commit transaction get_virtual_acc 

キーワードはホールドロック

于 2011-10-20T12:42:11.873 に答える