题
这个问题非常基础。我有一个JTable显示数据库中的缓存数据。如果用户单击一个单元格进行编辑,我想尝试锁定数据库中的该行。如果锁不成功,我想阻止编辑。
但我似乎无法找到任何干净的方法来实现这一目标。我错过了什么吗?
解决方案
因为您必须对点击进行测试,所以您无法使用模型的方式执行此操作,因此您应该尝试覆盖JTable的 public void changeSelection(int rowIndex,int columnIndex,boolean toggle,oolean extend)方法。如果该行被锁定,则不要调用super.changeSelection,它应该不选择该行。
其他提示
在编辑/设置值之前,通过TableModel.isCellEditable(row,col)询问表模型是否可以编辑此单元格。在这里你可以实现你的锁。在TableModel.setValue(row,col,val)之后你应该解锁它。但。锁定操作应该花费大量时间并使您的UI不负责任。它很糟糕。尝试不同的方法。懒惰失败怎么办?您锁定行,检查数据的有效性,如果数据较新,则会失败。如果数据正常,则将其放下。解锁。
Oracle有一种处理这个问题的好方法,但我不知道它有多普遍适用。
在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.editingStopped以在那里完成工作(您甚至可以检查该值是否已更改)
这样,在用户实际更改内容之前不会进行锁定。