[转]Wrapping multiple calls to SaveChanges() in a single transaction
本文转自:http://www.binaryintellect.net/articles/165bb877-27ee-4efa-9fa3-40cd0cf69e49.aspx
When you make any additions, modifications and deletions to an Entity Framework DbSet and call SaveChanges(), EF starts a new transaction and executes all the INSERT, UPDATE and DELETE operations inside that newly created transaction. If the call to SaveChanges() succeeds the underlying transaction is committed, otherwise the transaction is rolled back. In some cases you may want that multiple calls to SaveChanges() be executed in the same transaction. Luckily, Entity Framework 6 provides an easy way to accomplish the same.
Let's assume that you have an Entity Framework data model with Customer entity as shown below:

Now suppose that you wrote the following code to add two Customer records to the database.
NorthwindEntities db = new NorthwindEntities(); Customer obj1 = new Customer();
obj1.CustomerID = "ABCDE";
obj1.CompanyName = "Company 1";
obj1.ContactName = "Contact 1";
obj1.Country = "USA";
db.Customers.Add(obj1); db.SaveChanges();
Customer obj2 = new Customer();
obj2.CustomerID = "PQRST";
obj2.CompanyName = "Company 2";
obj2.ContactName = "Contact 2";
obj2.Country = "USA";
db.Customers.Add(obj2); db.SaveChanges();
In this case two calls to SaveChanges() are made. The first call adds the first Customer to the database and the second call adds the other Customer to the database. If the second call to SaveChanges() fails for some reason the first Customer still gets added to the database because each call to SaveChanges() runs in its own transaction.
Now let's modify this code as shown below:
using(NorthwindEntities db = new NorthwindEntities())
{
DbContextTransaction transaction = db.Database.BeginTransaction();
try
{
//insert a record
Customer obj1 = new Customer();
obj1.CustomerID = "ABCDE";
obj1.CompanyName = "Company 1";
obj1.ContactName = "Contact 1";
obj1.Country = "USA";
db.Customers.Add(obj1); //first call to SaveChanges() db.SaveChanges();
//insert another record
Customer obj2 = new Customer();
obj2.CustomerID = "PQRST";
obj2.CompanyName = "Company 2";
obj2.ContactName = "Contact 2";
obj2.Country = "USA";
db.Customers.Add(obj2); //second call to SaveChanges() db.SaveChanges();
transaction.Commit();
}
catch
{
transaction.Rollback();
}
}
Notice that the above code explicitly starts a transaction by calling BeginTransaction() method on the Database property of the data context. The BeginTransaction() returns a DbContextTransaction object which is stored in a local variable. This object is used to either commit or rollback the transaction later in the code.
The code then adds Customer entities as before and calls SaveChanges() after each addition. This time since our code is explicitly creating a transaction, both the calls to SaveChanges() are treated as the part of this transaction. If both the calls to SaveChanges() are successful we call Commit() method of DbContextTransaction object. If any of them fails we call the Rollback() method of DbContextTransaction object.
You can test the above code by setting the CustomerID of the second Customer to a string longer than five characters.
Note: There is also UseTransaction() method that can be used if you wish to couple EF operations with plain ADO.NET transactions.
That's it for now! Keep coding !!
[转]Wrapping multiple calls to SaveChanges() in a single transaction的更多相关文章
- Enlisting multiple 1-phase aware participants in the same transaction
In some cases it may be necessary to enlist participants that aren't two-phase commit aware into a t ...
- 从文件中读取字符-多次调用read characters from file multiple calls
[抄题]: 接口:int read4(char * buf)一次从文件中读取 4 个字符.返回值是实际读取的字符数. 例如,如果文件中只剩下 3 个字符,则返回 3.通过使用read4 接口,实现从文 ...
- Oracle Applications Multiple Organizations Access Control for Custom Code
档 ID 420787.1 White Paper Oracle Applications Multiple Organizations Access Control for Custom Code ...
- Entity Framework中DbContext结合TransactionScope提交事务的正确方式
问: I would like know what is the best possible way to implement transactions with DBContext. In part ...
- postgresql大批量数据导入方法
一直没有好好关注这个功能,昨天看了一下,数据库插入有瓶颈,今天研究了一下: 主要有以下方案: 1.使用copy从文件导入: copy table_001(a, b, "f", d, ...
- XA Transactions Restrictions on XA Transactions
小结: 1.innodb支持XA事务: 2.XA协议作为资源管理器(数据库)与事务管理器的接口标准: 3.提交或者回滚的点:必须所有的组件被提交或者被回滚: 4.2阶段 PC-1,TM告知所有RM要准 ...
- Wrapping calls to the Rational Functional Tester API——调用Rational Functional Tester封装的API
转自:http://www.ibm.com/developerworks/lotus/library/rft-api/index.html The Rational GUI automation to ...
- WCF Concurrency (Single, Multiple, and Reentrant) and Throttling
http://www.codeproject.com/Articles/89858/WCF-Concurrency-Single-Multiple-and-Reentrant-and Introduc ...
- Learning WCF Chapter1 Exposing Multiple Service Endpoints
So far in this chapter,I have shown you different ways to create services,how to expose a service en ...
随机推荐
- 「HEOI2016/TJOI2016」序列
题目链接 戳这 Solution 首先考虑最暴力的dp 我们设: \(f[i]\)表示选择\(i\)以后所能形成的满足条件的子序列的最大值 \(minx[i]\)表示\(i\)能转换为的最小值 \(m ...
- 声明函数指针、回调函数、函数对象------c++程序设计基础、编程抽象与算法策略
声明函数指针 #include<iostream> using namespace std; double a(double aa) { return aa; } int main() { ...
- python merge、concat合并数据集
数据规整化:合并.清理.过滤 pandas和python标准库提供了一整套高级.灵活的.高效的核心函数和算法将数据规整化为你想要的形式! 本篇博客主要介绍: 合并数据集:.merge()..conca ...
- python中局部变量和全局变量
局部变量,就是在函数内部定义的变量 不同的函数,可以定义相同的名字的局部变量,但是各用个的不会产生影响 局部变量的作用,为了临时保存数据需要在函数 在函数外边定义的变量叫做全局变量 全局变量能够在所有 ...
- RESTful API概念解析
什么是restful? REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为“表征状态转移”或“表现层状态转化”. ...
- Django权限控制进阶
一.一级菜单的排序 我们用字典存放菜单信息,而字典是无序的,当一级菜单过多时可能会出现乱序情况,因此需要给一级菜单排序 1.给一级菜单表的model中加一个weight权重的字段 ,权重越大越靠前 w ...
- Scanner类的用法
Scanner类,一个可以使用正则表达式来解析基本类型和字符串的简单文本扫描器. 用于扫描输入文本的实用程序.位于java.util包中. 使用Scanner接收键盘输入的字符,步骤: 1.导入Sca ...
- ExtJS 4.2.1学习笔记(一)——MVC架构与布局
1 ExtJS入门 1.1 支持所有主流浏览器 调试推荐:chrome.Safari.Firefox 1.2 推荐目录结构 - appname (包含所有程序代码,是根目录 ...
- N1 Armbian 安装 OpenMediaVault
前言 接上一篇继续折腾,这次在 N1 上进行一些本地化设置并安装使用 OpenMediaVault 步骤 使用 ssh 连接到 N1,修改系统源 cd /etc/apt cp sources.list ...
- java 加载properties
/** * 取得属性值,无值时返回默认值 * @param name String 属性名称 * @param defaultValue String 属性名称 * @return String 属性 ...