以下是代码:
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.RequiresNew))
{
DBContext.AddtoSomeTable(record);
System.Threading.Thread.Sleep(5000);
DBContext.SaveChanges();
MAX_ID = (from t in DBContext.SomeTable
select t.ID).Max();
scope.Complete();
}
据我所知,在范围完成之前,MAX_ID
应该是刚刚插入的新记录的ID。即使有两个用户同时提交,后一个用户应该等到第一个用户TransactionScope
完成。
但是,会发生什么是两个用户得到相同的MAX_ID
。这意味着在将第一个人的记录插入数据库之后,插入第二个人的记录,然后第一个人获得他的MAX_ID
。
我认为在事务中表被锁定以避免脏数据。有谁能解释一下?
编辑: ID字段自动递增
答案 0 :(得分:1)
在操作期间会执行不同类型和范围的锁定,并且随着锁定数量的增加,锁定范围将因锁定升级而更改。如果在单个事务中,您在单个表中插入/更新/删除单行,则很可能会采用独占行锁。当您更新/插入/删除该表中的更多行时,一旦累积了一定数量的行锁,锁升级就会将它们提升为页锁。累积足够的页面锁定,您将升级到表锁。
我不知道您尝试使用select max(id) from someTable
做什么,但是如果您希望它能反映您SaveChanges()
操作刚才所做的事情,那么很可能,您是&#39 ;重新创造竞争条件。
假设您正在使用SQL Server,内置函数 scope_identity()
将为您提供
插入同一范围内的标识列的最后一个标识值。 范围是一个模块:存储过程,触发器,函数或批处理。"
但是:如果在同一范围内,您可以在两个不同的表中插入一行,每个表都有一个标识列,
begin transaction
insert foo () ...
insert bar () ...
commit transaction
scope_identity()
为您提供范围生成的最后一个值(对于此示例中的表bar
)。