[英]namedParameterJdbctemplate update with more than one fields to update
[英]Update more than one row atomically
我需要執行一個select,然后以原子方式更新ResultSet
中的一些行。
我使用的代碼看起來像(簡化):
stmt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
rs = stmt.executeQuery("SELECT ...");
while (rs.next()) {
if (conditions_to_update) {
rs.updateString(...);
rs.updateRow();
}
}
updateRow()
更改了您正在更新的數據庫行,會發生什么? 有沒有辦法鎖定ResultSet
的行? 這里可能會發現一大堆技術和概念,當您開始考慮多線程/多請求應用程序時,事情開始變得相當棘手。
正如Iassevk所說,你應該考慮使用事務來確保你的更新的原子性 - 一個非常低級的例子是做一些事情:
...
con.setAutoCommit(false);
try {
while (rs.next()) {
if (conditions_to_update) {
rs.updateString(...);
rs.updateRow();
}
}
con.setAutoCommit(true);
} catch (Exception ex) {
//log the exception and rollback
con.rollback();
} finally {
con.close();
}
然后,所有更新將被批處理到同一事務中。 如果任何更新生成了異常(例如無效值或連接在結果中失敗),那么整個批次將被回滾。 (最后補充說因為我是它的冠軍; p)
但是,這不會解決您的第二個問題,即嘗試更新同一個表的兩種競爭方法 - 競爭條件。 在我看來,這里有兩種主要方法 - 每種方法都有它的優點和缺點。
最簡單的方法是鎖定表 - 這需要最少的代碼更改,但有一個很大的缺點。 假設,與大多數應用程序一樣,更多的是讀取寫入:鎖定表將阻止所有其他用戶查看數據,代碼可能會掛起,等待鎖定在連接超時之前釋放踢出並拋出異常。
更復雜的方法是確保以線程安全的方式實現執行這些更新的方法。 為此:
使用交易。
如果任何其他進程通過updateRow()更改了您正在更新的數據庫行,會發生什么? 有沒有辦法鎖定ResultSet中的行?
在Oracle中,您可以通過發出以下SQL來標記某些行以進行更新。
select cola, colB from tabA for update;
嘗試更新此行的下一個事務/線程/應用程序將獲得異常。 有關詳細信息,請參閱此處 - http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:4530093713805
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.