我該如何做'選擇更新',然後'更新'行使用ruby oci8。選擇與紅寶石oci8更新
我有一個表中只有1個記錄的兩個字段counter1和counter2。我想從表中選擇值,然後通過使用select for update來鎖定行來增加它們。
謝謝。
我該如何做'選擇更新',然後'更新'行使用ruby oci8。選擇與紅寶石oci8更新
我有一個表中只有1個記錄的兩個字段counter1和counter2。我想從表中選擇值,然後通過使用select for update來鎖定行來增加它們。
謝謝。
您需要確保autocommit
在您的連接上設置爲false。這是關鍵。然後,你會做以下步驟:
做你的選擇與最終FOR UPDATE子句(選擇列1,列2從MYTABLE的更新)。這將鎖定該行。
執行您的更新查詢。
發出一個顯式提交,它將釋放行上的鎖。
當然要記住,鎖定行只是將其鎖定在修改狀態。另一個會話仍然可以查詢這些行。例如,如果這是一個ID,並且獲取新ID的方式是查詢執行select max(id) + 1 from table
的表。鎖定行不會阻止另一個會話執行此選擇。
更好的辦法是跳過選擇並更新記錄,並使用returning
子句向您返回新的更新值。我從來沒有在Ruby OCI8中做過,所以我不確定它是否支持該功能。在更新該條款的文檔是在這裏:
http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/statements_10007.htm#i2126358
select_stmt = conn.prepare('select * from table_name for update')
select_stmt.exec
while row = select_stmt.fetch
conn.exec('update table_name set col = :1 where rowid = :2', 'val', select_stmt.rowid)
end
是的,我使用它作爲一個ID。我想選擇計數器的當前值(將其用作ID)並增加計數器。它是否阻止另一個會話執行「選擇更新」而不是「選擇」。使用'選擇更新'可以讓兩個會話仍然獲得相同的ID。我會嘗試'返回'條款。謝謝。 – user290870 2010-04-17 19:36:29
@ ash34:如果一個會話完成了「select for update」並且尚未提交或回滾,另一個會話執行「select for update」將阻止等待能夠獲得鎖定。您可以使用'select for update nowait'快速地使其他會話失敗。請在此處查看nowait的簡短說明:http://docstore.mik.ua/orelly/oracle/prog2/ch06_11.htm – 2010-04-18 04:57:07
如果您想要一個可靠的計數器,您應該使用一個序列。 – Martlark 2012-08-25 05:15:08