I use a pattern in my services where I have methods that always return an Entity but it is up to that method whether to retrieve it from the database or create it newly. I call these methods

getOrCreate*methods.

An example. Users can add a

Tagto aPost. When a user enters a tag “JavaScript”, I have a method in theTagServicecalledgetOrCreateTag(name: string). In that method I lower-case the name and try to fetch tags from the data base with that homogenized name. In case it finds it, it retrieves it, otherwise it will create a new Tag Entity and retrieve that.

This can lead to a problem. When two requests to the backend occur at the exact same time, with the exact same string, two tags with the same name are inserted. (You think it is unlikely? Please read the note below the article!)

What happens in slow-mo:

  1. Request A: asks whether that Tag exists
  2. Doesn’t find it
  3. Decides to create it
  4. Request B meanwhile asks whether that Tag exists
  5. Doesn’t find it
  6. Decides to create it
  7. Request A creates it
  8. Request B creates it

You may prevent that easily by a unique key constraint. But you only shift the issue. Because then step 8. will just fail with an exception leaving the application crashing.

One way to fix it, I will describe here implemented with TypeOrm.

Pessimistic lock

A lock of the database is always created during writing to the database. For example, step 7. and 8. both create a super short-living write lock. However, the issue was, that in step 2. and 5. respectively both requests couldn’t find it and **already **decided they are gonna write it to the database.

A pessimistic read lock is something you create manually. In TypeOrm you need the database connection for that.

#typeorm #typescript #concurrency

Solve Database Concurrency Issues with TypeOrm
16.20 GEEK