yesodweb / yesodweb/persistent

insertBy is not atomic

Open
#1,186 6 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Haskell
Stars
486
Forks
306
PR merge metrics
No merged PRs in 30d

Description

I'm using postgres 11.

insertBy function is supposed to return Left old in case where row with given unique key already exists, or Right new in case where given new record has been inserted. But in some cases, where insertBy is applied from different threads - it just not working this way, it's throwing runtime exception instead, because insert part of insertBy always assumes that record does not exist, which might be not true in case of mutithreading where second thread did insert right after first thread checked row existence. The problem there is that insertBy is not atomic, it's sequential composition of 2 functions - select and then maybe insert:

insertBy val = do
    res <- getByValue val
    case res of
        Nothing -> Right `liftM` insert val
        Just z -> return $ Left z

For some databases like postgres atomicity of inserts can be achieved with expressions like ON CONFLICT. Actually it's already used for atomic upsert function. Can insertBy be improved similar way? Or maybe there is working alternative already?

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reading the existing insertBy implementation and the upsert implementation, then compare their behavior under concurrent PostgreSQL inserts. Check how getByValue, insert, and PostgreSQL ON CONFLICT interact, and define the expected Left/Right result for competing threads. Done means insertBy handles an existing or concurrently inserted unique key without a runtime exception.

Written by the indexing model from the issue text.

Assessment

Tech stack
haskell, postgresql
Domain
databases
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.