update mytable set node_index=0 where id in (
SELECT
id
FROM mytable
WHERE
rownum<=10 and PROCS_DT is null
order by CRET_DT,PRTY desc)
I got this query as part of a previous answer to my question. Now how to lock the rows in the select query to make sure no other thread over writes my update.
It’s not clear to me that you have the problem you seem to think you have.
Updating a row in the table inherently places a row-level lock on that row. No other session can update that row until you release the lock by ending your transaction by committing or rolling back. Once you complete your transaction, other sessions are free to overwrite your update. There is no need or benefit to locking the rows in the
SELECT.If you are trying to write your application to avoid lost updates (i.e. you want to avoid another session updating the same rows that you did after you committed your transaction without showing the other user your updated data first), your application would need to implement some sort of additional locking. The most efficient would be to implement optimistic locking using some sort of
LAST_UPDATE_TIMESTAMPcolumn in the table. Assuming you added this column to the table if it doesn’t already have one, you would select theLAST_UPDATE_TIMESTAMPwhenever you queried data to present to the user and you would specify thatLAST_UPDATE_TIMESTAMPin yourUPDATE. If yourUPDATEupdated exactly 1 row, you know that no one had changed the data since you queried it. If yourUPDATEupdated 0 rows, you would know that the data had changed since you had queried it and your application would need to take appropriate action (i.e. re-querying the data, re-presenting it to the user, asking the user whether to keep any of the uncommitted changes they had made, etc.).Your query does have another problem, however. The
SELECTstatement is almost certainly not doing what you think (or intend) for it to do. This query gets an arbitrary 10 rows fromMYTABLEwherePROCS_DTis NULL and then orders those arbitrary 10 rows.Assuming that you actually want to get the “top 10” results, you would need to do the
ORDER BYin a subquery before applying theROWNUMpredicate, i.e.Or you could use an analytic function, i.e.