【发布时间】:2017-05-24 11:55:25
【问题描述】:
能否请您帮我确认/取消使用 Serializable 隔离级别的疑虑。
我想确保为以下方法AddUserTournament 选择了正确的IsolationLevel。每当执行此事务时,我想 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);
}
}
【问题讨论】:
-
EntityFramework 和 ADO.NET 是两种截然不同的技术,不要同时标记它们,就好像问题是指它们两者一样。根据您的代码,您使用的是 EntityFramework,因此 ADO.NET 完全无关
-
也只是您的
if逻辑或分步执行...还传入实体然后覆盖...在我的书中不适合编程。
标签: c# entity-framework transactions transactionscope