Предположим, у меня есть таблица account_profile
, в которой есть поле Score
, похожее на деньги учетной записи (тип базы данных - BIGINT(20)
, а тип EntityFramework - long
, потому что мне не нужно десятичное число). Теперь у меня есть следующие функции:Обеспечить параллельные (денежные) транзакции в Entity Framework?
public long ChangeScoreAmount(int userID, long amount)
{
var profile = this.Entities.account_profile.First(q => q.AccountID == userID);
profile.Score += amount;
this.Entities.SaveChanges();
return profile.Score;
}
Однако, я боюсь, что когда ChangeScoreAmount
называют несколько раз одновременно, окончательная сумма не будет правильным.
Вот мои текущие решения я имею в виду:
Добавление замок с статической переменной блокировки в функции
ChangeScoreAmount
, так как сам класс может быть реализован несколько раз, когда это необходимо. Это выглядит следующим образом:public long ChangeScoreAmount(int userID, long amount) { lock (ProfileBusiness.scoreLock) { var profile = this.Entities.account_profile.First(q => q.AccountID == userID); profile.Score += amount; this.Entities.SaveChanges(); return profile.Score; } }
Проблема заключается в том, я никогда не пробовал блокировку static
переменной, так что я не знаю, если это действительно безопасно, и если какой-нибудь тупик произойдет. Более того, может быть плохо, если где-то в другом месте вне этой функции, переход на поле Score
применяется на полпути.
КИ это уже не вариант, потому что мой сервер приложения будут работать на нескольких сайтах, что означает, что переменный запирающий не могут быть использованы
- Создания хранимой процедуры в базе данных, и называют это Хранятся процедура в функции. Тем не менее, я не знаю, существует ли «атомарный» способ создания этой процедуры хранения, поэтому его можно вызывать только один раз за раз, так как мне все еще нужно восстановить значение, изменив его, а затем обновить его снова?
Я использую MySQL Community 5.6.24 и MySQL .NET Connector 6.9.6, если это имеет значение.
ПРИМЕЧАНИЕ Мое серверное приложение может быть запущено на нескольких серверных машинах.
Возможный дубликат [получение блокировки статического объекта должен блокироваться на других потоках запросов?] (Http://stackoverflow.com/questions/7681725/acquiring-a-lock-on-a-static-object-should -block-on-other-request-threads) – FrankerZ