请您帮我确认/不确认使用Serializable isolationlevel我的怀疑。
我想确保我为以下方法IsolationLevel
选择了合适的AddUserTournament
。每当执行此事务时,我希望100%确定entity.seats
是最新的 - 防止任何其他事务同时添加用户。
我可以使用更宽松的IsolationLevel
实现此功能,还是这样做是正确的?
public void AddUserTournament(Tournament entity, User user)
{
try
{
// Add the user to tournament. Do this with a snapshot-isolationlevel
using (var transaction = _dbContext.Database.BeginTransaction(System.Data.IsolationLevel.Serializable))
{
try
{
// Get all users and include their relations to tournament
entity =
_dbContext.Tournaments.Where(e => e.TournamentId == entity.TournamentId)
.Include(t => t.Users)
.FirstOrDefault();
// Get the user
user = _dbContext.Users.SingleOrDefault(e => e.UserId == user.UserId);
// Check if there are available seats in the tournament and if user exist amoung enrolled users
if (entity != null && entity.Seats > entity.Users.Count &&
entity.Users.All(e => user != null && e.UserId != user.UserId))
{
// Add user
entity?.Users.Add(user);
// Save changes
_dbContext.SaveChanges();
// Commit transaction
transaction.Commit();
}
}
catch (Exception)
{
transaction.Rollback();
}
}
}
catch (DbEntityValidationException ex)
{
throw new FaultException(new FormattedDbEntityValidationException(ex).Message);
}
}
答案 0 :(得分:0)
我知道这不是回答你的问题,但我觉得我应该指出如何让它更具可读性。
只是展示如何将'if'重写为可读的内容。
//after you refactor it more you will see that this check is actually not needed.
if (entity != null)
{
//Called entity but represents a Tournament
//so the check is to see if the T has more seats than the current attending users
if(entity.Seats.Count > entity.Users.Count)
{
//this was to check if the user is already in the attending users
//if(entity.Users.All(e => user != null && e.UserId != user.UserId))
var userInSeats = entity.Users.Where(x=>x.UserId == user.UserId).SingleOrDefualt();
if(userInSeats == null )
{
// Add user
entity.Users.Add(user);
// Save changes
_dbContext.SaveChanges();
// Commit transaction
transaction.Commit();
}
}
}
然后你会看到不需要进行空检查,因为这个方法不能在没有实体的情况下被调用...除非你使用的是你在这里使用的泛型,否则我会称之为它们。