Links

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 everyCRUD 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.

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

  1. (转载)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 F ...

  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. ASP.NET MVC with Entity Framework and CSS一书翻译系列文章之第二章:利用模型类创建视图、控制器和数据库

    在这一章中,我们将直接进入项目,并且为产品和分类添加一些基本的模型类.我们将在Entity Framework的代码优先模式下,利用这些模型类创建一个数据库.我们还将学习如何在代码中创建数据库上下文类 ...

  4. Entity Framework Core 1.1 升级通告

    原文地址:https://blogs.msdn.microsoft.com/dotnet/2016/11/16/announcing-entity-framework-core-1-1/ 翻译:杨晓东 ...

  5. Entity Framework Core 实现MySQL 的TimeStamp/RowVersion 并发控制

    将通用的序列号生成器库 从SQL Server迁移到Mysql 遇到的一个问题,就是TimeStamp/RowVersion并发控制类型在非Microsoft SQL Server数据库中的实现.SQ ...

  6. 采用MiniProfiler监控EF与.NET MVC项目(Entity Framework 延伸系列1)

    前言 Entity Framework 延伸系列目录 今天来说说EF与MVC项目的性能检测和监控 首先,先介绍一下今天我们使用的工具吧. MiniProfiler~ 这个东西的介绍如下: MVC Mi ...

  7. 来,给Entity Framework热热身

    先来看一下Entity Framework缓慢的初始化速度给我们更新程序带来的一种痛苦. 我们手动更新程序时通常的操作步骤如下: 1)把Web服务器从负载均衡中摘下来 2)更新程序 3)预热(发出一个 ...

  8. 采用EntityFramework.Extended 对EF进行扩展(Entity Framework 延伸系列2)

    前言 Entity Framework 延伸系列目录 今天我们来讲讲EntityFramework.Extended 首先科普一下这个EntityFramework.Extended是什么,如下: 这 ...

  9. Entity Framework教程(第二版)

    源起 很多年前刚毕业那阵写过一篇关于Entity Framework的文章,没发首页却得到100+的推荐.可能是当时Entity Framework刚刚发布介绍EF的文章比较少.一晃这么多年过去了,E ...

随机推荐

  1. css li 不换行(布局,内容)

    参考这里 ------ 不换行的策略: 不换行原理: ul 和 li 默认都是 display:block; 的标签, 可以通过2种方式实现 li 的 不换行显示: * 将 li 设为 display ...

  2. git初体验(七)多账户的使用

    多github帐号的SSH key切换 我有两个github帐号,一个是个人所用,一个是为公司项目所用.如果是单用户(single-user),很方便,默认拿id_rsa与你的github服务器的公钥 ...

  3. C#-面向对象的三大特性——多态(虚方法与重写、抽象类、接口)

    多态 同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果.在运行时,可以通过指向基类的指针,来调用实现派生类中的方法. 编译时的多态性:编译时的多态性是通过重载来实现的.对于非虚的成员来说 ...

  4. Python3 连接Mysql

    代码: #!/usr/bin/env python # encoding: utf-8 """ @author: 侠之大者kamil @file: mysql_test. ...

  5. 启动Hadoop HA Hbase zookeeper spark

    服务器角色 服务器 192.168.58.180 192.168.58.181 192.168.58.182 192.168.58.183 Name CentOSMaster Slvae1 Slave ...

  6. linux中sh基本语法

    介绍:1 开头程序必须以下面的行开始(必须方在文件的第一行):#!/bin/sh  有人说是bash符号#!用来告诉系统它后面的参数是用来执行该文件的程序.在这个例子中我们使用/bin/sh来执行程序 ...

  7. 用WebBrowser采集渲染后的HTML页面

    主要用于微信的文章采集,如果用单纯的HttpClient采集,会出现页面无法渲染的情况: 经过研究发觉公众文章html页面是经过渲染之后显示的,那么思路来了,如果在dotnet的环境下,用WebBro ...

  8. mplayer依赖关系不满足

    mplayer以及其他fork出来的如mplayer2是命令行下的媒体播放器.一般ubuntu等的桌面系统都自带.然而自己使用了一段时间后突然出现缺少库文件,各种依赖关系不满足也未能重新安装.为了以后 ...

  9. 关于 SSV-ID: 4474 POC的分析和思考

    SSV-ID: 4474 SSV-AppDir: Discuz!漏洞 发布时间: 2008-11-21 (GMT+0800) URL:http://sebug.net/vuldb/ssvid-4474 ...

  10. Android登录界面实现

    花了一些时间实现了一个还算可以等登陆界面,主要是对这两天工作的一个总结:自定义按钮.编辑框.布局.全屏等. 效果如下: 获取代码:点这里