Why you shouldn't use Entity Framework with Transactions

EntityFramework

This is a .net ORM Mapper Framework from Microsoft to help you talking with your Database in an object oriented manner. Wikipedia

Database Transaction

A database transaction, by definition, must be atomic, consistent, isolated and durable. Database practitioners often refer to these properties of database transactions using the acronym ACID. Transactions in a database environment have two main purposes:

  1. To provide reliable units of work that allow correct recovery from failures and keep a database consistent even in cases of system failure, when execution stops (completely or partially) and many operations upon a database remain uncompleted, with unclear status.
  2. To provide isolation between programs accessing a database concurrently. If this isolation is not provided, the program's outcome are possibly erroneous. Wikipedia

.NET Transactions

A .NET Transaction can be used in different ways by different frameworks to support transactions. The .NET Transaction itself is not connected with the database by any means. MSDN

.NET Transactions and the EntityFramework

If you are using the Entity Framework during an opened TransactionScope, EntityFramework will open a new Transaction right with the next command that will be sent to the Database (CRUD Operation).

Consider this code block:

using (var transaction = new System.Transactions.TransactionScope())
{
// DBC = Database Command // create the database context
var database = new DatabaseContext(); // search for the user with id #1
// DBC: BEGIN TRANSACTION
// DBC: select * from [User] where Id = 1
var userA = database.Users.Find(1);
// DBC: select * from [User] where Id = 2
var userB = database.Users.Find(2);
userA.Name = "Admin"; // DBC: update User set Name = "Admin" where Id = 1
database.SaveChanges(); userB.Age = 28;
// DBC: update User set Age = 28 where Id = 2
database.SaveChanges(); // DBC: COMMIT TRANSACTION
transaction.Complete();
}

https://gist.github.com/SeriousM/e6b30db2b21e7e602655#file-bad_example-cs

The database.SaveChanges() call sends your changes to the database and executes them but they are not really persisted because you are in the database transaction scope. transaction.Complete() actually finishes the database transaction and your data is saved.

That behavior is actually cool and very useful, right?

NO. Absolutely not. full stop.

Why not using .NET Transactions along with EntityFramework

The default isolation mode is read committed and fits perfectly to 99% of your needs, eg. reading data. When you want to save the changes you made to the database (Create, Update, Delete), EntityFramework is smart enough to create a transaction without your notice behind the scenes to wrap the changes. You can be sure that everything will be saved or every change will be discarded (Atomicity).

By using transactions in EntityFramework, you change that behavior and force every CRUD operation during a transaction scope to be executed in serializable isolation mode which is the highest and most blocking type. No process will be able to access the tables you have touched (even reading from it) during your transaction. That can lead to Deadlocks pretty fast and you want to avoid them at all costs!

That's how the code looks like without the explicit usage of transactions:

// DBC = Database Command

// create the database context
var database = new DatabaseContext(); // search for the user with id #1
// DBC: select * from [User] where Id = 1
var userA = database.Users.Find(1);
// DBC: select * from [User] where Id = 2
var userB = database.Users.Find(2);
userA.Name = "Admin";
userB.Age = 28; // DBC: BEGIN TRANSACTION
// DBC: update User set Name = "Admin" where Id = 1
// DBC: update User set Age = 28 where Id = 2
// DBC: COMMIT TRANSACTION
database.SaveChanges();

https://gist.github.com/SeriousM/e6b30db2b21e7e602655#file-good_example-cs

Rule of Thumb: Save only once per task and don't use transactions.

Edit: thanks to @seimur - One thread should have access to one instance of DbContext which works best in web applications where every request acts as one thread. In windows applications every command or task should have one DbContext which is not shared. If you share the DbContext between threads you might run into issues like having reads sneaked into a foreign transaction.

Written by Bernhard Millauer

(转载)Why you shouldn't use Entity Framework with Transactions的更多相关文章

  1. Why you shouldn't use Entity Framework with Transactions

    Links EntityFramework This is a .net ORM Mapper Framework from Microsoft to help you talking with yo ...

  2. Entity Framework - Using Transactions or SaveChanges(false) and AcceptAllChanges()?

    LINK With the Entity Framework most of the time SaveChanges() is sufficient. This creates a transact ...

  3. 【极力分享】[C#/.NET]Entity Framework(EF) Code First 多对多关系的实体增,删,改,查操作全程详细示例【转载自https://segmentfault.com/a/1190000004152660】

      [C#/.NET]Entity Framework(EF) Code First 多对多关系的实体增,删,改,查操作全程详细示例 本文我们来学习一下在Entity Framework中使用Cont ...

  4. 转载:学习Entity Framework 中的Code First

    看完觉得不错,适合作为学习资料,就转载过来了 原文链接:http://www.cnblogs.com/Wayou/archive/2012/09/20/EF_CodeFirst.html 这是上周就写 ...

  5. 让Entity Framework支持MySql数据库(转载)

    转载地址:http://www.cnblogs.com/wintersun/archive/2010/12/12/1903861.html Entity Framework 4.0 也可以支持大名鼎鼎 ...

  6. 转载 8天掌握EF的Code First开发之Entity Framework介绍

    转载原地址:  http://www.cnblogs.com/farb/p/IntroductionToEF.html Entity Framework概要 Entity Framework是微软的O ...

  7. 转载Entity Framework 5.0(EF first)中的添加,删除,修改,查询,状态跟踪操作

    转载原出处:http://www.cnblogs.com/kenshincui/p/3345586.html Entity Framework将概念模型中定义的实体和关系映射到数据源,利用实体框架可以 ...

  8. 转载Entity Framework全面教程

    转载原地址:http://www.cnblogs.com/lsxqw2004/archive/2009/05/31/1495240.html#_Toc228672754 预备知识    2 LINQ技 ...

  9. 转载Entity Framework 4.1 DbContext使用记之三——如何玩转实体的属性值?

    Entity Framework 4.1 DbContext使用记之一——如何查找实体? DbSet.Find函数的使用与实现 Entity Framework 4.1 DbContext使用记之二— ...

随机推荐

  1. 将js进行到底:node学习4

    使用Node做web开发 HTTP与TCP 上一回使用node.js的NET(TCP)模块开发了一个聊天室demo.单纯用到了原始的TCP协议,可以说TCP是HTTP,SMTP,FTP的鼻祖了,后面的 ...

  2. mysql5.6和5.7的权限密码设置

    mysql5.6grant all privileges on *.* to root@'%' identified by "mysql_pwd" with grant optio ...

  3. 差旅日志i·长安&北京(更新于8.21_夜)

    大学之时,看到zealer王自如的差旅日志系列欲罢不能,扁平化的管理理念以及轻松的工作氛围,耳目一新的出差体验,抵消了部分不曾走入职场的紧张感甚至是恐惧感.如今初入职场也进入了职业生涯,特记录此次的差 ...

  4. 微软发布Microsoft Concept Graph和Microsoft Concept Tagging模型

    ​ Concept Graph和Microsoft Concept Tagging模型"> 当我们在讨论人工智能时,请注意,我们通常在讨论弱人工智能. 虽然我们现有的资源与之前可谓不同 ...

  5. 《ASP.NET Core 高性能系列》Span<T>和Memory<T>

    一.Span<T>概述 原文:Provides a type- and memory-safe representation of a contiguous region of arbit ...

  6. 《自拍教程35》段位二_Python面向过程函数

    Python批处理脚本只能处理较为简单的顺序执行的语句, 语句太多了,就有点乱...是时候升级一下了. 函数可以将多条语句分组封装,实现面向过程的,简单的模块化管理. 方便将语句实行"网格& ...

  7. node--fs

    1.fs模块内置方法 1)stat 检测是文件还是目录 fs.stat(fileAddress,(err,stats)=>{ //err 出错信息 //stats.isFile() 该东西是文件 ...

  8. 从头解决PKIX path building failed

    从头解决PKIX path building failed的问题 本篇涉及到PKIX path building failed的原因和解决办法(包括暂时解决和长效解决的方法),也包括HTTP和HTTP ...

  9. CSS中"position:relative"属性与文档流的关系

    前言 近期遇到一个问题--"position:relative"到底会不会导致元素脱离文档流?主流观点是不会,但都给不出一个有说服力的论据.最后我自己佐证了一番,总算有了个结果:& ...

  10. Java基础--面向对象(上)

    一.面向对象的概念 1.什么是面向对象? (1)面向对象是一种符合人类思维习惯的编程思想. (2)面向对象是一种思考问题的思维方式. 2.三种特性: (1)封装性 (2)继承性 (3)多态性 3.建立 ...