实体框架 - 事务



在所有版本的实体框架中,每当你执行SaveChanges()来插入、更新或删除数据库时,框架都会将该操作包装在一个事务中。当你调用 SaveChanges 时,上下文会自动启动一个事务,并根据持久化是否成功来提交或回滚它。

  • 这一切对你来说都是透明的,你永远不需要处理它。

  • 此事务仅持续足够长的时间来执行操作,然后完成。

  • 当你执行另一个此类操作时,将启动一个新事务。

实体框架 6 提供以下内容 -

Database.BeginTransaction()

  • 它是在现有 DbContext 中启动和完成用户事务的一种简单易用的方法。

  • 它允许在同一个事务中组合多个操作,因此要么全部提交,要么全部回滚为一个。

  • 它还允许用户更轻松地为事务指定隔离级别。

Database.UseTransaction()

  • 它允许 DbContext 使用在实体框架外部启动的事务。

让我们看一下以下示例,其中在单个事务中执行多个操作。代码如下 -

class Program {

   static void Main(string[] args) {

      using (var context = new UniContextEntities()) {

         using (var dbContextTransaction = context.Database.BeginTransaction()) {

            try {

               Student student = new Student() {
                  ID = 200, 
                  FirstMidName = "Ali", 
                  LastName = "Khan", 
                  EnrollmentDate = DateTime.Parse("2015-12-1")
               };

               context.Students.Add(student);

               context.Database.ExecuteSqlCommand(@"UPDATE Course SET Title = 
                  'Calculus'" + "WHERE CourseID = 1045");

               var query = context.Courses.Where(c ⇒ c.CourseID == 1045);

               foreach (var item in query) {
                  Console.WriteLine(item.CourseID.ToString()
                     + " " + item.Title + " " + item.Credits);
               }

               context.SaveChanges();
               var query1 = context.Students.Where(s ⇒ s.ID == 200);

               foreach (var item in query1) {
                  Console.WriteLine(item.ID.ToString() 
                     + " " + item.FirstMidName + " " + item.LastName);
               }

               dbContextTransaction.Commit();
            } catch (Exception) {
               dbContextTransaction.Rollback();
            }

         }
      }
   }
}
  • 启动事务需要底层存储连接处于打开状态。

  • 因此,调用 Database.BeginTransaction() 将打开连接(如果尚未打开)。

  • 如果 DbContextTransaction 打开了连接,则在调用 Dispose() 时将关闭它。

广告