Entity framework 如果我有一个具有多个CRUD操作的事务,Sql server如何/何时更新记录时间戳值

Entity framework 如果我有一个具有多个CRUD操作的事务,Sql server如何/何时更新记录时间戳值,entity-framework,sql-server-2008-r2,entity-framework-5,asp.net-mvc-5,Entity Framework,Sql Server 2008 R2,Entity Framework 5,Asp.net Mvc 5,我正在开发一个asp.net mvc web应用程序,并使用实体框架将表映射到模型类中。 我有一个表示VM的模型类:- public partial class TMSVirtualMachine { public int TMSVirtualMachineID { get; set; } public int ServerID { get; set; } public int RoleID { get; set; } pu

我正在开发一个asp.net mvc web应用程序,并使用实体框架将表映射到模型类中。 我有一个表示VM的模型类:-

public partial class TMSVirtualMachine
    {
        public int TMSVirtualMachineID { get; set; }
        public int ServerID { get; set; }
        public int RoleID { get; set; }
        public Nullable<int> BackUpStatusID { get; set; }
        public Nullable<int> StatusID { get; set; }
        public Nullable<int> MonitoreID { get; set; }
        public Nullable<decimal> TotalStorage { get; set; }
        public string Comment { get; set; }
        public byte[] timestamp { get; set; }
        public Nullable<long> IT360SiteID { get; set; }

        public virtual TMSServer TMSServer { get; set; }
//cde goes here…
    }
当前,如果两个用户同时调用上述方法,其中一个用户将获得DbUpdateCurrentException,因为尝试保存虚拟机时的时间戳与检索虚拟机时的时间戳不同。 我的问题基本上是SQLServer2008R2如何管理时间戳列。让我们以以下场景为例:-

  • 首先用户检索5个VM,然后生成5个SQL更新命令并保存

  • 第二个用户检索5个VM,然后生成5个SQL update,当尝试保存时,EF将检测到至少一个VM的时间戳已更改,并引发DBUPdateException

现在,当第一个用户执行5个SQL更新操作时,他的工作在5个更新操作成功之前不会被保存,因为5个更新操作被包装在一个操作中

Q1)那么sql server 2008 r2何时会更改5台服务器的时间戳列,何时完成事务?或者何时保存单个更新操作?如果事务失败,sql server是否会返回旧的时间戳值

很抱歉邮件太长,但我试图寻找一个明确的答案,但无法得出最终结论。

非常清楚:

是一种数据类型,它公开数据库中自动生成的唯一二进制数。时间戳通常用作对表行进行版本戳的机制。存储大小为8字节。时间戳数据类型只是一个递增的数字,不保留日期或时间。要记录日期或时间,请使用datetime数据类型

您可以使用行的timestamp列轻松确定行中的任何值自上次读取以来是否发生了更改。如果对行进行了任何更改,则会更新时间戳值

因此,很明显,当行更改时,时间戳会被修改

:如果应用程序读取一行,对其进行修改,并尝试保存数据库中的更改以及自读取后更改的时间戳,则会引发并发异常

至于交易,您缺少的是“”概念。当对行进行更改时,timestamp列将更改。但是,如果另一个连接尝试读取此行,会发生什么情况取决于隔离级别:可以锁定该行,直到事务完成(因此另一个连接必须等到该时刻),或者另一个连接可以读取新的未写入值,也可以读取旧值。这取决于隔离级别

默认情况下,在SQL Server中,隔离级别为:

阅读承诺 指定语句无法读取已修改但未由其他事务提交的数据。这可以防止脏读。数据可以由当前事务中单个语句之间的其他事务更改,从而导致不可重复的读取或虚拟数据。此选项是SQL Server默认设置


感谢您的回复,实际上,当我检查sql profiler时,我可以看到EF使用“set transaction isolation level read committed.”,这意味着EF将防止脏读,并将锁定由事务修改的记录,直到事务提交。是这样吗?但是使用readcommitted不会阻止不可重复的读取。是的,没错。但是,不要对此太担心。这真的有可能发生还是真的很奇怪?在最坏的情况下,其中一个用户将得到一个异常,这是一个暂时的问题。如果您认为有可能,您应该决定如何解决此问题,并捕获异常来解决它。根据我的经验,在大多数(几乎所有)应用程序中,并发问题发生的可能性可以忽略不计。如果你认为这是正确的答案,请接受它,这样对其他人有用。
public int changeVMsServer(AssignVMsToServer s, string username)
        {
            int count = 0;

var currentvms = tms.TMSVirtualMachines.Where(a => a.ServerID == s.serverIDForm);
            foreach (var v in currentvms)
            {
 v.ServerID = s.serverIDTo;
tms.Entry(v).State = EntityState.Modified;
count++;

}
SaveChanges();

            return count;
 }