(转载)Why you shouldn't use Entity Framework with Transactions
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:
- 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.
- 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的更多相关文章
- 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 ...
- 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 ...
- 【极力分享】[C#/.NET]Entity Framework(EF) Code First 多对多关系的实体增,删,改,查操作全程详细示例【转载自https://segmentfault.com/a/1190000004152660】
[C#/.NET]Entity Framework(EF) Code First 多对多关系的实体增,删,改,查操作全程详细示例 本文我们来学习一下在Entity Framework中使用Cont ...
- 转载:学习Entity Framework 中的Code First
看完觉得不错,适合作为学习资料,就转载过来了 原文链接:http://www.cnblogs.com/Wayou/archive/2012/09/20/EF_CodeFirst.html 这是上周就写 ...
- 让Entity Framework支持MySql数据库(转载)
转载地址:http://www.cnblogs.com/wintersun/archive/2010/12/12/1903861.html Entity Framework 4.0 也可以支持大名鼎鼎 ...
- 转载 8天掌握EF的Code First开发之Entity Framework介绍
转载原地址: http://www.cnblogs.com/farb/p/IntroductionToEF.html Entity Framework概要 Entity Framework是微软的O ...
- 转载Entity Framework 5.0(EF first)中的添加,删除,修改,查询,状态跟踪操作
转载原出处:http://www.cnblogs.com/kenshincui/p/3345586.html Entity Framework将概念模型中定义的实体和关系映射到数据源,利用实体框架可以 ...
- 转载Entity Framework全面教程
转载原地址:http://www.cnblogs.com/lsxqw2004/archive/2009/05/31/1495240.html#_Toc228672754 预备知识 2 LINQ技 ...
- 转载Entity Framework 4.1 DbContext使用记之三——如何玩转实体的属性值?
Entity Framework 4.1 DbContext使用记之一——如何查找实体? DbSet.Find函数的使用与实现 Entity Framework 4.1 DbContext使用记之二— ...
随机推荐
- 模型压缩之Channel Pruning
论文地址 channel pruning是指给定一个CNN模型,去掉卷积层的某几个输入channel以及相应的卷积核, 并最小化裁剪channel后与原始输出的误差. 可以分两步来解决: channe ...
- 基于seo的话 一个页面里的h1标签应该控制在多少个
不能出现多个,一个页面只能出现一次,次数多了就会造成权重分散
- ES:在线迁移集群索引,数据不丢失
一.背景 生产环境由于某些原因需要跨机房迁移ES集群,或者同机房原有集群中所有节点全部更换,期间ES索引要求完整,客户端请求中断不超过五分钟. 二.应用场景 1.同机房不同集群之间数据迁移: 2.跨机 ...
- 马云也看好!VR在2016年能否得到质变
在2015年10月底有消息传出,国外虚拟现实公司Magic Lea的新一轮融资吸引到中国互联网巨鳄--阿里巴巴公司的关注.据透露,阿里巴巴极有可能为Magic Lea投资2亿美元.这虽然是阿里巴巴第一 ...
- ubuntu 代理设置
在学习工作中使用vagrant作为开发环境已经有很长一段时间了,使用ubuntu 作为开发系统 在使用中发现,即使修改了apt的source.list源文件,在面对一些开发中需要的软件工具的时候,不可 ...
- 从未来看 C#
前言 如今 C# 虽然发展到了 8.0 版本,引入了诸多的函数式特性,但其实在 C# 未来的规划当中,还有很多足以大规模影响现有 C# 代码结构和组成的特性,本文中将会对就重要的特性进行介绍,并用代码 ...
- 7-49 求前n项的阶乘之和 (15 分)
从键盘输入一个整数n,求前n项的阶乘之和,1+2!+3!+...+n!的和 输入格式: 输入一个大于1的整数.例如:输入20. 输出格式: 输出一个整数.例如:2561327494111820313. ...
- Webpack 核心开发者 Sean Larkin 盛赞 Vue
dev.io 近日邀请了 Webpack 核心开发者 Sean Larkin 回答开发者提问,其中几个问提比较有意思,和掘金的小伙伴们分享一下. 先上点前菜: 有一个开发者问 Sean 如何成为一个热 ...
- Java——JDBC
今天给大家更新一篇我自己学习Java——JDBC的经验 Java中JDBC是(Java DataBase Connectivity)的简称,由java语言编写的类和接口组成,可为多种关系型数据库提供了 ...
- JS的类
JS在创建之初不支持类,因为很多开发者为处理类创建了好多代码库,最终导致ES6引入了类. ES5及更早的版本都不支持类,与类最接近的是:创建一个构造器,然后将方法指派到该构造器的原型上.就是原型继承. ...