首页 > 数据库 >如何快速实现数据库读写分离

如何快速实现数据库读写分离

时间:2023-03-25 19:56:30浏览次数:47  
标签:readEntityNames readConnectionString 读写 分离 writeConnectionString var using 数据库

实现读写分离可以使用AOP(面向切面编程)思想,通过划分事务的读写属性,将其分别交由读写数据库实例来处理。下面是实现读写分离的代码示例:

```
using  System;
using  System.Linq;
using  System.Transactions;
using  System.Collections.Generic;
using  Microsoft.EntityFrameworkCore;
using  Microsoft.EntityFrameworkCore.Diagnostics;

namespace  DataAccessLayer
{
        public  class  MainDbContext  :  DbContext
        {
                private  readonly  string  _readConnectionString;
                private  readonly  string  _writeConnectionString;
                private  readonly  List<string>  _readEntityNames;
 
                public  MainDbContext(
                        string  readConnectionString,
                        string  writeConnectionString,
                        List<string>  readEntityNames)
                {
                        _readConnectionString  =  readConnectionString;
                        _writeConnectionString  =  writeConnectionString;
                        _readEntityNames  =  readEntityNames;
                }
 
                protected  override  void  OnConfiguring(DbContextOptionsBuilder  optionsBuilder)
                {
                        optionsBuilder.ConfigureWarnings(
                                warnings  =>  warnings.Throw(CoreEventId.FirstWithoutOrderByAndFilterWarning));
 
                        //  读写分离
                        optionsBuilder.UseSqlServer(_writeConnectionString)
                                .EnableSensitiveDataLogging();
                        base.OnConfiguring(optionsBuilder);
                }
 
                protected  override  void  OnModelCreating(ModelBuilder  modelBuilder)
                {
                        //  全部从主库读写
                        modelBuilder.Model.SetReadOnly(false);
                        base.OnModelCreating(modelBuilder);
                }
 
                public  override  int  SaveChanges()
                {
                        //  事务范围内打开连接
                        using  (var  transactionScope  =  new  TransactionScope(TransactionScopeOption.Required,
                                new  TransactionOptions  {  IsolationLevel  =  IsolationLevel.ReadUncommitted,  Timeout  =  TimeSpan.FromSeconds(30)  }))
                        {
                                //  划分事务
                                var  writeEntities  =  ChangeTracker.Entries()
                                        .Where(e  =>  e.State  ==  EntityState.Added  ||  e.State  ==  EntityState.Modified  ||  e.State  ==  EntityState.Deleted)
                                        .Select(e  =>  e.Entity.GetType().Name).Distinct().Except(_readEntityNames)
                                        .ToList();
                                var  readEntities  =  ChangeTracker.Entries()
                                        .Where(e  =>  e.State  ==  EntityState.Unchanged)
                                        .Select(e  =>  e.Entity.GetType().Name).Distinct().Intersect(_readEntityNames)
                                        .ToList();
 
                                //  读写分离处理
                                bool  isRead  =  false;
                                var  connection  =  this.Database.GetDbConnection();
                                connection.Open();
 
                                foreach  (var  entity  in  writeEntities)
                                {
                                        this.Database.UseTransaction(null);
                                        isRead  =  false;
                                }
 
                                foreach  (var  entity  in  readEntities)
                                {
                                        this.Database.UseTransaction(Transaction.Current);
                                        isRead  =  true;
                                }
 
                                //提交事务
                                var  result  =  base.SaveChanges();
                                transactionScope.Complete();
                                return  result;
                        }
                }
        }
}
```

在代码中,MainDbContext继承自DbContext类,包含了读、写两个连接字符串,以及需要读取的表名的列表。在OnConfiguring()方法中,通过调用UseSqlServer()方法来配置写连接字符串。在SaveChanges()方法中,通过划分事务的读写属性,将其分别交由读写数据库实例来处理。这样就实现了基于AOP思想的读写分离。

标签:readEntityNames,readConnectionString,读写,分离,writeConnectionString,var,using,数据库
From: https://www.cnblogs.com/yswenli/p/17255453.html

相关文章

  • mysql数据库备份与恢复
    环境:CentOS7.9mysql-5.71.数据库准备,建表createdatabaseschool;CREATETABLEstudent(idINT(10)NOTNULLUNIQUEPRIMARYKEY,nameVARCHAR(20)NOTNULL,se......
  • 在windows系统中设置MySQL数据库
    MySQL搭建效果图step1:下载安装包https://downloads.mysql.com/archives/community/step2:解压后即完成安装step3:创建my.ini配置文件(注意路径)[mysqld]......
  • Python爬虫基础——06-文件的读写
    2.12文件2.12.1文件的打开和关闭:在python中,使用open函数,可以打开一个已存在的文件夹,或者创建一个新文件open(文件路径,访问模式)示例如下:f=open('test.txt','w')文件路径......
  • 2023爬虫学习笔记 -- MongoDB数据库
    一、下载安装mongodb1、下载地址https://www.mongodb.com/try/download/community2、一路下一步安装,路径不要出现空格中文等特殊字符3、设置环境变量将bin目录地址放到path......
  • 阿里云数据库RDS迁移导入数据时报错:Specified key was too long; max key length is 76
    近期由于新申请了新的阿里云数据库RDS,需要把之前的数据迁移过去,结果通过各种方式去导入数据,都一直报错.报错信息:Indexcolumnsizetoolarge.Themaximumcolumnsize......
  • Java使用IntelliJ IDEA创建控制台程序并通过JDBC连接到数据库
    1、创建一个java控制台程序并测试首先,直接新建一个默认的空的Java模块即可,随便取个名字在src目录下右键->新建->创建一个包,随便取个名字在包中创建一个Test类,写个helloworld......
  • 若依框架---前后端分离项目部署实践
    一、环境准备系统:centos7(可以买ECS或本地安装虚拟机)安装:git、jdk、maven、npm、mysql、redis、nginx具体安装方式详见codesheep出品的pdf文档点击下载提取码:gogo,当然,有些也......
  • 数据库设计
    一、用户登录信息表(Sys_UserLogOn)序号列名数据类型长度小数位标识主键外键允许空默认值说明1F_Idvarchar500 是 否 用户登录主键2F_UserIdvarchar500   是 用户主键3......
  • IDEA中sql语句的模糊查询查不到数据库中的信息
    IDEA中使用sql的模糊查询查找数据库中的用户姓名,查找不到相关信息。1、排查sql语句没有问题2、确认数据库的编码使用了gbk 最后去查了jdbc驱动,发现驱动信息中没有配......
  • MySQL数据库备份与恢复
    一,备份,恢复为什么要备份灾难恢复:硬件故障、软件故障、自然灾害、黑客攻击、误操作测试等数据丢失场景参考链接:https://www.toutiao.com/a6939518201961251359/ ......