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. Shell的特殊字符

    # 有意义的“#”符合 echo ${PATH#*:} # 参数替换,不是一个注释 echo $(( 2#101011 )) # 进制转换,可以是任意进制,不是一个注释 “.” .字符匹配,这是作为正 ...

  2. 利用Nginx或koa

    最近在做上传的图片的需求,思考上传之后的图片怎么访问的问题,因为后端是Node,一开始尝试写一个专门的接口通过传入图片的path来查找,试了一下感觉并不理想,因为要为每种类型的文件设置Content- ...

  3. JavaScript 语言精粹笔记3

    方法 毒瘤 糟粕 记录一下阅读蝴蝶书的笔记,本篇为书中最后一部分:方法.代码风格.优美的特性.毒瘤.糟粕等. 方法 这一章主要介绍了一些方法集.这里写几个我不太熟悉的方法和要点吧. array.joi ...

  4. Nginx502,504和499错误解决方案

    499错误解决方案 499错误是什么?让我们看看NGINX的源码中的定义: ngx_string(ngx_http_error_495_page), /* 495, https certificate ...

  5. CSS——NO.3(CSS选择器)

    */ * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:text.cpp * 作者:常轩 * 微信公众号:Worldhe ...

  6. C++走向远洋——63(项目二2、两个成员的类模板)

    */ * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:text.cpp * 作者:常轩 * 微信公众号:Worldhe ...

  7. 数据库及MySQL概述

    #什么是数据 用来描述事物的符号记录.可以是数字.文字.图形等,有多种形式,经过数字化之后存入计算机 #什么是数据库 数据库(Database)就是一个用来存放数据库的仓库,是按照一定的数据结构来组织 ...

  8. KEMET新型电容器推动了电动汽车技术的发展

    前言:KEMET成立于1919年,总部位于佛罗里达州劳德代尔堡,是全球领先的高端电子组件供应商,KEMET为客户提供业内最广泛的电容器技术选择,以及不断扩大的机电设备,电磁兼容性解决方案和超级电容器. ...

  9. 微信小程序最新授权方法,getUserInfo

    20180511微信小程序正式关闭原先getUserInfo的逻辑 不再允许自动弹出授权框. 方法一: index.wxml(准备一个用于给用户授权的页面,我这里直接用了一个全屏按钮) <vie ...

  10. 用vue开发一个公众号商城SPA——1.前期准备和写页面

    使用vue开发公众号商城 第1篇记录项目准备.搭建,写页面遇到第问题以及总结,持续更新 公司最近接了个商城项目,包括PC端商城.微信公众号网页商城.后台管理系统.这几天在做微信公众号商城,又新接触了很 ...