LiteDB: [question] How to prevent race condition?

I am using LiteDB in a web application.

However, I am having this issue: I am storing a list of users, and each user has a data usage number. In each request, the user data usage number is loaded from LiteDB, and is increased. But this is my problem: if the client makes many simultaneous requests, the data usage number will be loaded before it is updated, resulting in an incorrect data usage.

To explain again: In database: [usage: 20]

request 1:

  • thread 1: server loads usage (is 20)
  • thread 1: does some processsing (adds 10), does not update user in litedb collection yet request 2 (happens during request 1’s data processing):
  • thread 2: server loads usage (is 20) <-- This is my problem, I want to lock the user so other requests can’t happen until first request processing is done
  • thread 2: server adds 10
  • thread 1 saves user (now usage is 30)
  • thread 2 saves user (now usage is 30)

the problem is that thread 2 doesn’t wait for thread 1 to finish, and incorrect final value is stored. I am using NancyFx with async/await requests; each request spawns a new thread.

i am using transactions only when saving the value.

thanks

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Comments: 17 (2 by maintainers)

Most upvoted comments

Within the database.

Table: user_locks Fields : Bool write_lock default value off Bool read _lock default value off.

Before processing user data from user table for either read (select) or write (update / insert)

Do check of contents of the values of user_locks table

In structure of example: Table: users Id | username | data… 1| Steve | djdjsjs 2 | John | djdbdbdb 3 | most | dhdjsnsn

Table: user_locks Id | read_lock | write_lock 1 | 0 | 0 2 | 0 | 0 3 | 0 | 0

Program example

To explain again: In database: [usage: 20]

request 1:

  • thread 1: server loads usage (is 20)
  • thread 1: does some processsing (adds 10), does not update user in

litedb collection yet request 2 (happens during request 1’s data processing):

  • thread 2: server loads usage
  • thread 2: server adds 10
  • thread 1 saves user
  • thread 2 saves user

On each of user data in thread do the following: When reading user data Check read_lock If set to true do a wait loop for x. seconds then check again till. read_lock is false Set write_lock to true Read user data. Do processing Set write_lock to false

When writing (saving / updating) Check write_lock Do wait loop till value is false (same as read_lock logic) Set read_lock to true Do update / insert command etc… Set read_lock to false On Jan 6, 2017 2:51 AM, “nictaylr” notifications@github.com wrote:

could you please explain in more detail @xX-MLG-Xx https://github.com/xX-MLG-Xx

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/mbdavid/LiteDB/issues/415#issuecomment-270801691, or mute the thread https://github.com/notifications/unsubscribe-auth/AVQ2C80Zs82SF8AlecmV1oiQ7-VYxb9iks5rPY_8gaJpZM4LcSIP .