默认情况当你执行SaveChanges()的时候(insert update delete)来操作数据库时,Entity Framework会把这个操作包装在一个事务里,当操作结束后,事务也结束了。

EF6中的 Database.ExecuteSqlCommand()也会启用一个事务,事务的隔离级别是默认级别(Read Commited)。

虽然这种框架默认的事务处理机制对于大多数情况下已经够用了,但是是EF6为我们提供了API,让我们能够更加灵活地对自己代码中的事务进行控制。

一、在EF中使用事务

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Data.Entity;
  4. using System.Data.SqlClient;
  5. using System.linq;
  6. using System.Transactions;
  7. namespace TransactionsExamples
  8. {
  9. class TransactionsExample
  10. {
  11. static void StartOwnTransactionWithinContext()
  12. {
  13. using (var context = new BloggingContext())
  14. {
  15. using (var dbContextTransaction = context.Database.BeginTransaction())
  16. {
  17. try
  18. {
  19. context.Database.ExecuteSqlCommand(
  20. @"UPDATE Blogs SET Rating = 5" +
  21. " WHERE Name LIKE '%Entity Framework%'"
  22. );
  23. var query = context.Posts.Where(p => p.Blog.Rating >= 5);
  24. foreach (var post in query)
  25. {
  26. post.Title += "[Cool Blog]";
  27. }
  28. context.SaveChanges();
  29. dbContextTransaction.Commit();
  30. }
  31. catch (Exception)
  32. {
  33. dbContextTransaction.Rollback();
  34. }
  35. }
  36. }
  37. }
  38. }
  39. }

上面通过一个using语句块把要使用事务的操作起来,调用context.Database.BeginTransaction()启动一个事务,最后分别通过dbContextTransaction.Commit();和dbContextTransaction.Rollback();来提交或回滚事务。

注意:开启一个事务需要事务所有在的数据库链接是打开的,因此当所在数据库链接没有打开时Database.BeginTransaction()就会打开一个数据库链接。上面调用context.Database.BeginTransaction()是没有参数的,你可以调用这个BeginTransaction()其它重载函数来控制事务的隔离级别,如果没传参数将会使用默认的隔离级别。

二、传递一个已存在的事务

EF中可以传递一个存在的事务给context:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Data.Entity;
  4. using System.Data.SqlClient;
  5. using System.Linq;
  6. sing System.Transactions;
  7. namespace TransactionsExamples
  8. {
  9. class TransactionsExample
  10. {
  11. static void UsingExternalTransaction()
  12. {
  13. using (var conn = new SqlConnection("..."))
  14. {
  15. conn.Open();
  16. using (var sqlTxn = conn.BeginTransaction(System.Data.IsolationLevel.Snapshot))
  17. {
  18. try
  19. {
  20. var sqlCommand = new SqlCommand();
  21. sqlCommand.Connection = conn;
  22. sqlCommand.Transaction = sqlTxn;
  23. sqlCommand.CommandText =
  24. @"UPDATE Blogs SET Rating = 5" +
  25. " WHERE Name LIKE '%Entity Framework%'";
  26. sqlCommand.ExecuteNonQuery();
  27. using (var context =
  28. new BloggingContext(conn, contextOwnsConnection: false))
  29. {
  30. context.Database.UseTransaction(sqlTxn);
  31. var query = context.Posts.Where(p => p.Blog.Rating >= 5);
  32. foreach (var post in query)
  33. {
  34. post.Title += "[Cool Blog]";
  35. }
  36. context.SaveChanges();
  37. }
  38. sqlTxn.Commit();
  39. }
  40. catch (Exception)
  41. {
  42. sqlTxn.Rollback();
  43. }
  44. }
  45. }
  46. }
  47. }
  48. }

三、TransactionScope事务

EF中让多个数据库操作作为一个整体的事务来处理除了上面使用事务传递来实现外,还可以利用TransactionScope对象来处理,如下:

  1. using System.Collections.Generic;
  2. using System.Data.Entity;
  3. using System.Data.SqlClient;
  4. using System.Linq;
  5. using System.Transactions;
  6. namespace TransactionsExamples
  7. {
  8. class TransactionsExample
  9. {
  10. static void UsingTransactionScope()
  11. {
  12. using (var scope = new TransactionScope(TransactionScopeOption.Required))
  13. {
  14. using (var conn = new SqlConnection("..."))
  15. {
  16. conn.Open();
  17. var sqlCommand = new SqlCommand();
  18. sqlCommand.Connection = conn;
  19. sqlCommand.CommandText =
  20. @"UPDATE Blogs SET Rating = 5" +
  21. " WHERE Name LIKE '%Entity Framework%'";
  22. sqlCommand.ExecuteNonQuery();
  23. using (var context =
  24. new BloggingContext(conn, contextOwnsConnection: false))
  25. {
  26. var query = context.Posts.Where(p => p.Blog.Rating > 5);
  27. foreach (var post in query)
  28. {
  29. post.Title += "[Cool Blog]";
  30. }
  31. context.SaveChanges();
  32. }
  33. }
  34. scope.Complete();
  35. }
  36. }
  37. }
  38. }

注意:上面提交事务是通过TransactionScope实例的Complete方法来提交的。

可以看到使用TransactionScope使我们代码简化了不少,但是要注意的是TransactionScope也有一些限制:

1、需要NET 4.5.1及以上

2、不能和Database.UseTransaction()方式结合起来使用

3、sql语句中不能有DLL操作

4、不能在云场景中使用,除非你保证只有一个数据库连接。(支场景中不支持分布式事务)

EF6中使用事务的方法的更多相关文章

  1. EF6 中tracking log使用方法总结

    先上一段最近项目中的代码,此代码可以放到自己项目中的dbContext中 public override Task<int> SaveChangesAsync() { List<Au ...

  2. 在Hibernate中分别使用JDBC和JTA事务的方法

    在Hibernate中使用JDBC事务 Hibernate对JDBC进行了轻量级的封装,它本身在设计时并不具备事务处理功能.Hibernate将底层的JDBCTransaction或JTATransa ...

  3. 在MySQL中设置事务隔离级别有2种方法:

    在MySQL中设置事务隔离级别有2种方法: 1 在my.cnf中设置,在mysqld选项中如下设置 [mysqld] transaction-isolation = READ-COMMITTED 2 ...

  4. @Transactional 同一个类中无事务方法a()内部调用有事务方法b()的问题

    https://blog.csdn.net/u010235716/article/details/90171802 1. 事务的4种特性       序号 参数 含义1 原子性(Atomicity) ...

  5. Entity Framework入门教程(19)---EF中使用事务

    EF中使用事务 这节介绍EF6中事务的使用.EF core中事务的使用方式和EF6中一模一样. 1.EF中的默认的事务 默认情况下,当我们执行一个SaveChanges()方法时就会新建了一个事务,然 ...

  6. 数据库事务及其EF中如何处理事务

    一.基础知识 1)         使用事务级别ReadUnCommited 会产生脏读现像,意味着读取到的为UnCommited(未提交)的数据.怎么理解呢?在使用该隔离级别的事务开始后.更新了数据 ...

  7. 存储过程中使用事务,sql server 事务,sql事务

    一.存储过程中使用事务的简单语法       在存储过程中使用事务时非常重要的,使用数据可以保持数据的关联完整性,在Sql server存储过程中使用事务也很简单,用一个例子来说明它的语法格式: 代码 ...

  8. 【MySQL】漫谈MySQL中的事务及其实现

    最近一直在做订单类的项目,使用了事务.我们的数据库选用的是MySQL,存储引擎选用innoDB,innoDB对事务有着良好的支持.这篇文章我们一起来扒一扒事务相关的知识. 为什么要有事务? 事务广泛的 ...

  9. Abp公共连接和事务管理方法

    Conection 和事务管理在使用数据库的应用中是一个最重要的概念.当你打开一个连接,开始一个事务,如何来处理这些连接等等. 您也许知道,.NET使用了连接池.所以,创建一个连接实际上是从连接池里得 ...

随机推荐

  1. Lucene第二篇【抽取工具类、索引库优化、分词器、高亮、摘要、排序、多条件搜索】

    对Lucene代码优化 我们再次看回我们上一篇快速入门写过的代码,我来截取一些有代表性的: 以下代码在把数据填充到索引库,和从索引库查询数据的时候,都出现了.是重复代码! Directory dire ...

  2. 详解go语言的array和slice 【二】

    上一篇已经讲解过,array和slice的一些基本用法,使用array和slice时需要注意的地方,特别是slice需要注意的地方比较多.上一篇的最后讲解到创建新的slice时使用第三个索引来限制sl ...

  3. 二叉树终极教程--BinarySearchTree

    BinarySearchTreeMap 的 实现 public interface Map<K extends Comparable<K>, V> { void put(K k ...

  4. Go语言备忘录:基本数据结构

    本文内容是本人对Go语言的变量.常量.数组.切片.映射.结构体的备忘录,记录了关键的相关知识点,以供翻查. 文中如有错误的地方请大家指出,以免误导!转摘本文也请注明出处,多谢! 参考书籍<Go语 ...

  5. Dynamic Inversions II 逆序数的性质 树状数组求逆序数

    Dynamic Inversions II Time Limit: 6000/3000MS (Java/Others) Memory Limit: 128000/64000KB (Java/Other ...

  6. 支持向量机SVM(一)

    [转载请注明出处]http://www.cnblogs.com/jerrylead 1 简介 支持向量机基本上是最好的有监督学习算法了.最开始接触SVM是去年暑假的时候,老师要求交<统计学习理论 ...

  7. php用PHPWord库生成word文档的例子

    <?php require_once '../libs/PHPWord/PHPWord/IOFactory.php'; require_once '../../config.php'; $PHP ...

  8. PHP字符串替换str_replace()函数4种用法详解

    mixed str_replace ( mixed $search , mixed $replace , mixed $subject [, int &$count ] )该函数返回一个字符串 ...

  9. RewriteMap(apache)

    最近在工作中发现一个陌生的语法,apache服务器站点rewrite配置文件里的,开始还以为是apache的一种新语法,以这个词网上搜索,没搜到相关文章,跟老同事请教了一下,说这个是RewriteMa ...

  10. JavaWeb基础之JdbcUtils工具类1.0

    2016年12月20日,第一次学习JDBC.看的是传智播客崔希凡老师的视频,东北口音很是风趣幽默,技术之牛让人膜拜.2017年9月21日,再次重温web知识,分享JdbcUtils工具类,用以接下来的 ...