【发布时间】:2022-11-16 13:03:37
【问题描述】:
我需要在插入数据之前进行状态检查,但我发现即使我设置了隔离级别,EF Core 也不会锁定表以防止读取。
这是我的代码:我需要锁定SignTicket表和SignTicketApproval表,从读取到提交,这样其他人就不会得到关于票证状态的虚假数据。但即使我设置了隔离级别,我仍然可以在 SSMS 中读取表。
我需要一个表级锁,因为这是一个insert-only表,每次操作都必须检查最新记录以确定ticket的状态。
谢谢你。
using var _context = new EFContext();
using var transaction = _context.Database.BeginTransaction(System.Data.IsolationLevel.Serializable);
var ticket = _context.SignTicket
.Include(x => x.SignTicketApproval)
.ThenInclude(x => x.Result)
.Single(x => x.Id == cancelSignTicketRequest.SignTicketId.ToLong());
if (_signTicketService.GetTicketStatus(ticket) != TicketStatus.Open)
{
throw new SignTicketStatusException("Ticket status is not open", ticket);
}
// Create new fake approval request and set __Cancel as outcome
var utcNow = DateTime.UtcNow;
var cancelSignoff = new SignTicketApproval()
{
AssignedTo = cancelSignTicketRequest.CanceledBy,
Description = "User cancel",
CreateTime = utcNow,
Result = new SignTicketApprovalResult()
{
Canceled = true,
ApproverEmail = cancelSignTicketRequest.CanceledBy,
CreateTime = utcNow,
Outcome = ReservedButton.CancelButton,
Comment = cancelSignTicketRequest.Reason
}
};
ticket.SignTicketApproval.Add(cancelSignoff);
_context.SaveChanges();
transaction.Commit();
【问题讨论】:
-
隔离级别不做表锁,它会锁定您读取的行,但同样不会阻止其他事务查询数据或插入新行。 (它可以阻止在指定键并可能在锁定范围内的插入)因此,例如使用可序列化隔离级别,在断点之后尝试对该行进行更新将被阻止,但读取不会,而其他行的更新则不会。当并发很重要时,我建议使用在接受任何更改之前检查的并发时间戳/行版本。
标签: c# .net sql-server entity-framework-core