Jourmand
Jourmand

Reputation: 948

Prevent insert the same record that comes from clients at the same time with entity framework

I have Api that config when calling from Clint, it insert a PhoneNumber & Current Date Time. In my office I have 4 Clint that calling this api at the same time, that will result in 4 inserting data, therefore, I add conditioner to prevent this situation, the code like this:

public bool IsExistIn10Seconds(string number)
{
    var item = DbContext.Histories
               .Where(o => o.Number == Number && 
                           o.EntryDateTime.DateTime >= DateTime.Now.AddSeconds(-10))
               .FirstOrDefault();
}

Code used for Insert Data:

public void Save(History model)
{
    var exist = _historyRepository.IsExistIn10Seconds(model.Number);
    if (exist) return;
    _historyRepository.Add(model);
    _historyRepository.Save();
}

If any record exist in item variable, that means record already add, But this solution is not working and in production stage, it still add 4 records. result after publish in production stage is there any solution to Prevent multiple insert in same time (Entity Framework, MVC Core 2.0)

Upvotes: 1

Views: 2603

Answers (4)

GraemeMiller
GraemeMiller

Reputation: 12263

If they are child records e.g. Phone number entiry is a parent that has history you could enforce adding via the parent phone number and use a timestamp property on the parent for concurrency control. http://learn.microsoft.com/en-us/aspnet/core/data/ef-mvc/concurrency. If just individual records db unique index is probably best. If you need to do it in app you would probably need to enforce it via reservation pattern or locking.

Upvotes: 0

Jourmand
Jourmand

Reputation: 948

I using Locking principle:

public class LockObject
{
    public static object LockObjectSatet = new object();
}

And Then:

public void Save(History model)
{
    lock (LockObject.LockObjectSatet)
    {
        var exist = _historyRepository.IsExistIn10Seconds(model.Number);
        if (exist) return;
        _historyRepository.Add(model);
        _historyRepository.Save();
    }
}

Upvotes: 0

AmiNadimi
AmiNadimi

Reputation: 5725

Check if there is any duplicate entries in the database that have the same details as what you're trying to add. If not, then it's a new version and you should add it, if so then it's a duplicate and you should do whatever you want to handle that situation.

if (repository.Get(x => x.Major == newVersion.Major && 
    x.Minor == newVersion.Minor && x.Build == newVersion.Build)
    .Count() > 0)
{
     //notify the user that they are making a duplicate entry
}
else
{
     repository.SaveChanges();
}

More

Upvotes: -1

Vladislav Kostenko
Vladislav Kostenko

Reputation: 1205

If you want uniqueness on some field you can add Unique Index on the field. This will prevent from dupes in table. You will have exception on attempt of multiple insert. Another approach is you could use db transaction with serializable isolation level to read existing rows (check existence) and write new row in one transaction. It will also lead to exception on multiple insert.

Upvotes: 2

Related Questions