zoukankan      html  css  js  c++  java
  • EF6学习笔记二十五:分布式事务

    要专业系统地学习EF推荐《你必须掌握的Entity Framework 6.x与Core 2.0》。这本书作者(汪鹏,Jeffcky)的博客:https://www.cnblogs.com/CreateMyself/

    现在来到分布式事务。在弄这个之前我对分布式一点经验也没有。简单来说一下分布式,就是你有多个数据库。

    不过我碰到的“MSDTC不可用”的问题实在是无法解决。所以只能是记录一下我遇到的问题,和一些过程。

    上次我们知道平时一般的操作,都是会默认被事务包裹,当我们调用一次SaveChanges方法就会开启一个事务。

    然后了解到EF中提供的BeginTransaction()和UseTransaction()两个方法。

    BeginTransaction()能够让我们像ADO中使用事务的那种方式使用。而且调用多个savechanges方式只会开启一个事务,但是必须要调用一次SaveChanges才能成功操作数据。

    UseTransaction方法允许上下文加入已经运行的事务中,它可以接受一个事务对象。

    那么如果我们的数据存在多个数据库中呢?就有了分布式的考虑。怎么做呢?

    你可能想到可以通过嵌套上下文,使用UseTransaction来接受另一个上下文的事务。但是不可以。因为UseTransaction接受的事务对象不是EF中定义的事务,而是System.Data.Common.DbTransaction类型的,也就是ADO中的事务类型

    那么我们ado和EF混着用?这个应该是可以的,但是我没有去试。

    那么现在就直接来说一个很重要的类:TransactionScop

    可以看到这种方式正是我们想要的,DB1_Context 和 DB4_Context 分别对应两个数据库,一个本地,还有一个是我远程服务器上的数据库。 通过TransactionScop就可以实现分布式事务。

    using (var scope = new TransactionScope(TransactionScopeOption.RequiresNew))
    {
        var db1_ctx = new DB1_Context();
        var db4_ctx = new DB4_Context();
        try
        {
            db1_ctx.Students.Add(new Student { Name = "小懵", Score = 11 });
            db1_ctx.SaveChanges();
    
            db4_ctx.Books.Add(new Book { Name="西游记",PageSize=670});
            db4_ctx.SaveChanges();
            scope.Complete();
        }
        catch (Exception e)
        {
            throw e;
        }
        finally
        {
            db1_ctx.Dispose();
            db4_ctx.Dispose();
        }
    }
    View Code

    看一下我项目的文件结构

    这里我要记录一下使用程序包管理控制台做数据迁移,将不同的上下文分别创建不同的文件夹

    比如我为DB1_Context上下文开启迁移

    enable-migrations -ContextTypeName:_20190131.DbContexts.DB1_Context -MigrationsDirectory:MigrationsDB1

    ContextTypeName就是上下文的类型名称,MigrationsDirectory就是你将要创建的文件夹

    如果说你记不住命令,可以写了“-”后按Tab键就会出现提示。如果说没有提示,那么就是你前面的语句写错了。命令不同区分大小写,但是你自己提供的值还是要区分的,毕竟DBContext和dbcontext在VS中还是两个不同的两个类

    命令后面的冒号可写可不写,比如:ContextTypeName:DBcontext  或者 ContextTypeName DBcontext  我还是觉得写上问号好一点,可读性高。

    那么添加迁移文件

    add-migration -ConfigurationTypeName:_20190131.Migrations.DB1.Configuration -Name:db1001

    更新到数据库

    update-database -ConfigurationTypeName:_20190131.Migrations.DB1.Configuration -verbose

    现在来记录一下我碰到的问题,我也不知道会这么麻烦,对我来说不过是多了一个数据库而已。

    首先我通过EF在MSSQL上的一个实例创建了两个数据库DB1和DB2,于是我执行上面的代码,发现报错了,他说MSDTC不可用。

    那么MSDTC是什么?协调跨多个数据库、消息队列、文件系统等资源管理器的事务。如果停止此服务,这些事务将会失败。如果禁用此服务,显式依赖此服务的其他服务将无法启动。

     

    反正涉及到分布式就需要配置MSDC,网上有很多图文并茂的配置,但都是一样的。难道都不一样么?难道怎么配置都行么?呵呵

    最终我没有解决这个问题。

    然后我想到是不是因为两个数据库都是在本地,都是在同一个实例中造成的。于是我今天又在我的服务器上安装了一个MSSQL2017,费了

    老半天劲终于我本地数据库能够连接远程服务器的数据库实例了。

    但是还是出席那MSDTC不可用的问题。行吧,就到这里。 

  • 相关阅读:
    ef unitofwork 主从表更新
    自己写的enum转换的一个扩展,
    最近在做政务项目,此种项目,本来并不大,主要原因呢,就是要理好业务需要。
    sql server创建外键,子母表,级联删除。
    js querySelector与getElementById
    写一个system.data.entity的simpledatarepo,实现crudq这些功能,不需要引入entityframework,直接可以使用,用到objectset
    无法更新 EntitySet“W_ReceiveData”,因为它有一个 DefiningQuery,而 <ModificationFunctionMapping> 元素中没有支持当前操作的 <InsertFunction> 元素。
    Kubernetes v1.17 版本解读 | 云原生生态周报 Vol. 31
    开放下载 | 《Knative 云原生应用开发指南》开启云原生时代 Serverless 之门
    有了 serverless,前端也可以快速开发一个 Puppeteer 网页截图服务
  • 原文地址:https://www.cnblogs.com/jinshan-go/p/10348655.html
Copyright © 2011-2022 走看看