How can two DELETE queries deadlock in Postgres?
You should instead ignore expired cache entries, so you will not depend on a frequent delete operation for cache expiration:
SELECT valueFROM cacheWHERE key = 'Ethan is testing6460437' and (ttl is null or ttl<now());
And have another job that periodically chooses keys to delete skipping already locked keys, which has to either force a well defined order of deleted row, or, better, skip already locked for update rows:
with delete_keys as ( select key from cache where ttl is not null and now()>ttl for update skip locked)delete from cachewhere key in (select key from delete_keys);
If you can't schedule this periodically you should run this cleanup like randomly once every 1000 runs of your select query, like this:
create or replace function delete_expired_cache()returns voidlanguage sqlas $$ with delete_keys as ( select key from cache where ttl is not null and now()>ttl for update skip locked ) delete from cache where key in (select key from delete_keys);$$;SELECT valueFROM cacheWHERE key = 'Ethan is testing6460437' and (ttl is null or ttl<now());select delete_expired_cache() where random()<0.001;
You should avoid writes, as they are expensive. Don't delete cache so often.
Also you should use timestamp with time zone
type (or timestamptz
for short) instead of simple timestamp
- especially if you don't know why - a timestamp
is not the thing most think it is - blame SQL standard.