code_junkie

Select unlocked row in Postgresql

Nov 13th, 2011
127
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.23 KB | None | 0 0
  1. Select... order by id desc limit 1 for update
  2.  
  3. Users
  4.  
  5. -----------------------------------------
  6. ID | Name | flags
  7. -----------------------------------------
  8. 1 | bob | 0
  9. 2 | fred | 1
  10. 3 | tom | 0
  11. 4 | ed | 0
  12.  
  13. select * from queue where flag=0 order by id desc for update;
  14. update queue set flag=1 where id=:id;
  15. --if you really want the lock:
  16. select * from queue where id=:id for update;
  17. ...
  18.  
  19. Select... order by id desc offset THREAD_NUMBER limit 1 for update
  20.  
  21. UPDATE users SET flags = 1 WHERE id = ( SELECT id FROM users WHERE flags = 0 ORDER BY id DESC LIMIT 1 ) RETURNING ...;
  22.  
  23. SELECT ... WHERE FLAG=0 ... FOR UPDATE
  24.  
  25. UPDATE ... SET FLAG=1 WHERE ID=:id
  26.  
  27. select *
  28. into l_sms
  29. from sms
  30. where prefix_id = l_prefix_id
  31. and invoice_id is null
  32. and pg_try_advisory_lock(sms_id)
  33. order by suffix
  34. limit 1;
  35.  
  36. Users
  37.  
  38. -----------------------------------
  39. ID | Name | flags
  40. -----------------------------------
  41. 1 | bob | 0
  42. 2 | fred | 1
  43. 3 | tom | 0
  44. 4 | ed | 0
  45.  
  46. BEGIN;
  47.  
  48. UPDATE "Users"
  49. SET ...
  50. WHERE ...;
  51. RETURNING ( column list );
  52.  
  53. COMMIT;
  54.  
  55. FOR messages in select * from public.messages where sendTime >= CURRENT_TIMESTAMP - '1 SECOND'::INTERVAL AND sendTime <= CURRENT_TIMESTAMP + '1 SECOND'::INTERVAL AND sent is FALSE FOR UPDATE LOOP
  56. -- DO SMTH
  57. END LOOP;
  58.  
  59. FOR messages in select * from public.messages where sendTime >= CURRENT_TIMESTAMP - '1 SECOND'::INTERVAL AND sendTime <= CURRENT_TIMESTAMP + '1 SECOND'::INTERVAL AND sent is FALSE AND is_locked(msg_id) IS FALSE FOR SHARE LOOP
  60. -- DO SMTH
  61. END LOOP;
  62.  
  63. CREATE OR REPLACE FUNCTION is_locked(integer) RETURNS BOOLEAN AS $$
  64. DECLARE
  65. id integer;
  66. checkout_id integer;
  67. is_it boolean;
  68. BEGIN
  69. checkout_id := $1;
  70. is_it := FALSE;
  71.  
  72. BEGIN
  73. -- we use FOR UPDATE to attempt a lock and NOWAIT to get the error immediately
  74. id := msg_id FROM public.messages WHERE msg_id = checkout_id FOR UPDATE NOWAIT;
  75. EXCEPTION
  76. WHEN lock_not_available THEN
  77. is_it := TRUE;
  78. END;
  79.  
  80. RETURN is_it;
  81.  
  82. END;
  83. $$ LANGUAGE 'plpgsql' VOLATILE COST 100;
Add Comment
Please, Sign In to add comment