Reputation: 580
How can I make sure that my update queries do not wait for a commit when the same row is locked by another transaction that has not yet committed?
I tried using a trigger before update on a column and wanted to check for contention for the row but since the trigger is itself not executed if there is a contention on the same row, i had to drop that option. This is how I designed the trigger and wished to check inside begin for row contention
create or replace trigger trig_row_contention_sig
before update of most_used on tbl_sig for each row
But the trigger is also getting queued. Is there any other way? I would also be happy if I can discard those update queries post issuing and checking for contention for the same rows THAN wait.
Upvotes: 1
Views: 1216
Reputation: 146239
You can implement a pessimistic locking strategy. This attempts to acquire the lock before issuing the commit:
declare
cursor c1 is
select * from your_table
where id = 1
for update of whatever -- this is the pessimistic lock
nowait -- abandon the attempt if row is already locked
;
r1 c1%rowtype;
begin
open c1;
fetch c1 into r1;
update your_table
set whatever = whatever + 1
where current of c1;
close c1;
commit; -- release the lock
end;
This toy code has NOWAIT, so the query fails if the row is already locked. We can also WAIT for a specified timeout or wait indefinitely (what you're doing now).
Another neat feature of the SELECT ... FOR UPDATE syntax is SKIP LOCKED, which allows us to implement queuing. Find out more.
"Why does the trigger not work ? I mean when i have set it up to run before update, shouldnt it also be executed before row locking."
That's not what before update
means. All triggers are effectively ON <<event>>
. Triggers fire when the event happens. The trigger can't fire until the row is actually updated.
The before
and after
triggers refer to the state of the row. In a before update
trigger we can reference :OLD values and manipulate :NEW values. In an after update
trigger we can reference :OLD values and :NEW values but cannot change :NEW values.
Upvotes: 4