問題はかなり基本的なものです。データベースからキャッシュされたデータを表示する JTable があります。ユーザーが編集のためにセルをクリックした場合、データベース内のその行をロックしようとします。ロックが成功しない場合は、編集を禁止したい。
しかし、これを達成するためのきれいな方法を見つけることができないようです。何か不足していますか?
値を編集/設定する前に、このセルが編集可能かどうかを TableModel.isCellEditable(row,col) を介してテーブル モデルに尋ねます。ここでロックを実装できます。そして TableModel.setValue(row,col,val) の後、これをロック解除する必要があります。しかし。ロック操作には多くの時間がかかり、UI が無責任になります。そして、それは悪いです。別のアプローチを試してください。怠惰な失敗はどうですか?行をロックし、データの有効性を確認し、データが新しい場合は失敗します。データに問題がなければ、それらを置きます。ロック解除。
オラクルにはこれを処理する優れた方法がありますが、それがどの程度普遍的に適用できるかはわかりません。
Oracle では、SELECT ステートメントでFOR UPDATEを使用して、読み取り時にレコードをロックできます。
たとえば、表示する行をフェッチする場合:
select * into v_row from my_table where my_table_id = 1
for update;
これにより、読み取りは許可されますが、更新は防止されます。別のトランザクションがロックしている場合、トランザクションはそれが利用可能になるまで (またはタイムアウトになるまで) 待機します。ロックしようとしたときにステートメントが例外をスローするようにするには、NOWAITを追加します。
select * into v_row from my_table where my_table_id = 1
for update nowait;
行がすでにロックされている場合は、次のようになります。
ORA-00054: resource busy and acquire with NOWAIT specified.
それが役立つことを願っています。
クリックでテストする必要があるため、モデルの方法を使用できないため、JTableのpublic void changeSelection(int rowIndex、int columnIndex、boolean token、oolean extend)メソッドをオーバーライドしてみてください。行がロックされている場合は、super.changeSelectionを呼び出さないでください。そうすれば、行は選択されないままになります。
代わりに、ユーザーが実際に何かを変更するまで待ってから、JTable.editingStoppedをオーバーライドしてそこで作業を行うことができます(値が変更されたかどうかを確認することもできます)
そうすれば、ユーザーが実際に何かを変更するまで、ロックは行われません。