本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《
TransactionScope是.net平台基于的分布式事务组件,它默认为本地事务,同时当系统有需要时可以自动提升为分布式事务,而对系统的前提是要开启MSDTC服务,必要时需要在数据库服务器与应用服务器之间添加hosts的映射,这些在之前已经写过很多文章了,在这里不再说了。
在efcore平台时,你使用TransactionScope将会出现异常,微软会提示你去查看相关资料,这回资料挺准!https://docs.microsoft.com/en-us/ef/core/saving/transactions
和之前的ef一样,在进行saveChanges()操作时,本身就是一个事务块,而大叔仓储习惯把每个操作curd都有自己的saveChanges里,而把数据上下文的savechanges对外隐藏,所以如果你要对两个仓储进行insert操作时,你需要添加一个外层的事务来保证数据一致性,这时微软给出了解决方案。
using (var context = new BloggingContext())
using (var transaction = context.Database.BeginTransaction())
context.Blogs.Add(new Blog { Url = "http://blogs.msdn.com/dotnet" });
context.SaveChanges();
context.Blogs.Add(new Blog { Url = "http://blogs.msdn.com/visualstudio" });
context.SaveChanges();
var blogs = context.Blogs
.OrderBy(b => b.Url)
.ToList();
// Commit transaction if all commands succeed, transaction will auto-rollback
// when disposed if either commands fails
transaction.Commit();
catch (Exception)
// TODO: Handle failure
三 不同上下文之间实现事务
对于前面的TransactionScope来说,如果是不同的数据上下文来说,我们是无法实现事务操作的,有些同学可以能说它应该被提升为分布式的,但对于EF来说,它是不同实现的,但进行efcore时代之后,这个问题得到了解决!
Cross-context transaction (relational databases only)
You can also share a transaction across multiple context instances. This functionality is only available when
using a relational database provider because it requires the use of DbTransaction and DbConnection,
which are specific to relational databases.
上面说明,可以实现一个跨数据上下文的事务,只关系型数据库支持!这个功能大叔认为非常必要,但看它下面给出的实例是针对一个数据上下文的,并不多个上下文的交
叉事务,即并不是两个数据库之间的事务。
using (var context1 = new BloggingContext(options))
using (var transaction = context1.Database.BeginTransaction())
context1.Blogs.Add(new Blog { Url = "http://blogs.msdn.com/dotnet" });
context1.SaveChanges();
using (var context2 = new BloggingContext(options))
context2.Database.UseTransaction(transaction.GetDbTransaction());
var blogs = context2.Blogs
.OrderBy(b => b.Url)
.ToList();
// Commit transaction if all commands succeed, transaction will auto-rollback
// when disposed if either commands fails
transaction.Commit();
catch (Exception)
// TODO: Handle failure
而如果真正使用多个上下文进行事务的话,同样会出现问题:
var options = new DbContextOptionsBuilder<DemoContext>()
.UseMySql("Server=localhost;DataBase=test2;UID=root;Password=root;charset=utf8;port=3306;SslMode=None")
.Options;
using (var context = new DemoContext(options))
using (var transaction = context.Database.BeginTransaction())
var user = new UserInfo
AddTime = DateTime.Now,
Email = "test@sina.com",
UserName = "test"
context.UserInfo.Add(user);
context.SaveChanges();
using (var context2 = new TaxContext())
context2.Database.UseTransaction(transaction.GetDbTransaction());
context2.UserInfo.Add(new UserInfo { AddTime = DateTime.Now, Email = "tax_test", UserName = "tax" });
context2.SaveChanges();
transaction.Commit();
出现下面异常:告诉你,你的数据库连接不是当前的连接
System.InvalidOperationException:“The specified transaction is not associated with the current connection.
Only transactions associated with the current connection may be used.”
不知道什么时候EF可以解决多数据库事务的问题,当前你可以使用最终一致性的分布式事务来做这事,不过我们还是一起期待中微软为我们提出更简单的解决方案,一个事务
是否为分布式的,应该看数据库所在服务器是否相同,而不是数据库连接串是否一致!
感谢微软这么完整的解释!
本文转自博客园张占岭(仓储大叔)的博客,原文链接:DotNetCore跨平台~EFCore废弃了TransactionScope取而代之的Context.Database.BeginTransaction,如需转载请自行联系原博主。
UWP: 在 UWP 中使用 Entity Framework Core 操作 SQLite 数据库
原文:UWP: 在 UWP 中使用 Entity Framework Core 操作 SQLite 数据库
在应用中使用 SQLite 数据库来存储数据是相当常见的。在 UWP 平台中要使用 SQLite,一般会使用 SQLite for Universal Windows Platform 和 SQLite PCL 之类的库,前者是 SQLite 引擎库,而后者则提供了用于操作数据库的 API ,不过自从 Windows Fall Creators Update 之后,我们有了新的选择。