DataRabbit 轻量的数据访问框架(19)-- 读写分离与隔离级别

简介: 在高并发的系统中,我们常采用多数据库分散放置、读写分离、细粒度的隔离级别设定等策略来提高系统的性能。DataRabbit3.3 以及以上版本对这三种策略都给予了内置的支持。 (1)数据库分散放置:对于较大型的系统,在设计数据库时,我们可以根据业务范围将其设计为多个数据库,而不是一个,然后将这些数据库部署在不同的物理服务器上,以分担负载。

      在高并发的系统中,我们常采用多数据库分散放置、读写分离、细粒度的隔离级别设定等策略来提高系统的性能。DataRabbit3.3 以及以上版本对这三种策略都给予了内置的支持。

(1)数据库分散放置:对于较大型的系统,在设计数据库时,我们可以根据业务范围将其设计为多个数据库,而不是一个,然后将这些数据库部署在不同的物理服务器上,以分担负载。当然,如果已经设计好的数据库,也可以采用水平分区或垂直分区的方式来达到类似的效果。

(2)读写分离:在高性能的系统中,这是最常采用的策略。在SqlServer中,可以采用事务型的订阅/发布模型来实现这种策略。在这种策略中,有一个Master DB 和多个(或一个)Slave DB,其中所有的Slave DB是只读的,而Master DB支持读写,当Master DB中的数据发生变化时,所有Slave DB会自动与其同步(可能会有稍微的延迟)。

(3)细粒度的隔离级别:比如,对于某些要求不高的查询可以采用ReadUncommitted的隔离级别来读取数据。

      DataRabbit.Application.TransactionScopeFactoryProvider<TSourceKey,TSlaveSuitKey> 类可以支持数据库分散放置和读写分离。它支持【1套主/N套从】数据库实例。 【一套】表示支持一个系统运行的不可或缺的相互协作的多个数据库。

      TransactionScopeFactoryProvider类图结构如下所示:      

      

      其中泛型参数TSourceKey是用来表示数据源标志的类型,比如我们可以用字符串来为每个数据库(数据源)命名,那么TSourceKey便可使用string类型。

      泛型参数TSlaveSuitKey是用来表示每套从库的【套标志】的类型,比如,我们每套Slave库中包含5个数据库(这与Master中的5个是一一对应的),而我们可以提供比如3套Slave库以支持超大负载的数据读取,于是我们就要为这三套Slave库加以不同的标志以区分。

      其中有用于注入Master DB数据库连接信息的Dictionary属性:MasterDataConfigurationDictionary,键便是TSourceKey类型,是每个数据源的标志,其值是用于封装数据库连接信息的DataConfiguration,这个类大家已经很熟悉了。而SlaveSuitDictionary用于注入多套从库的数据库连接信息。当然你已经知道,MasterDataConfigurationDictionarySlaveSuitDictionary中每一套的项是一一对应的。还有一个小技巧,如果你现在的系统还不够大,但是以后会采用倒读写分离策略,那么暂时你可以将Master和Slave配置为指向同一个数据库,这是没有问题的,等系统做大了以上,需要Slave的支持时,只要修改一下配置即可。

      

      DBOperationLogger属性用于记录数据库的所有操作和访问产生的异常信息。如果不设置,则表示不记录这些信息,关于DBOperationLogger的介绍,可以参考这里

      接下来我们再看GetFactory方法:

      TransactionScopeFactory GetFactory(TSourceKey sourceKey,  bool  fromMaster);

      其第一个参数表示要访问哪个数据库,第二个参数表示是要访问Master库还是Slave库。我们要注意到,当系统采用多套从库时,GetFactory()方法会随机的返回某套从库的TransactionScopeFactory,从而达到自动负载均衡的目的。 当然你也可以通过GetSlaveFactory()方法来返回指定标志的某套从库的TransactionScopeFactory。

      如此,我们可以这样来使用读写分离机制 -- 比如,我们有一个任务只是读取数据库,而不会有任何修改行为,那么就从Slave库中读取:

            IList < Student >  list  =   null ;
            TransactionScopeFactory factory 
=   this .transactionScopeFactoryProvider.GetFactory(DBSourceType.Basic,  false );
            
using  (TransactionScope scope  =  factory.NewTransactionScope( false ))
            {
                IOrmAccesser
< Student >  accesser  =  scope.NewOrmAccesser < Student > ();
                list 
=  accesser.GetAll();
                scope.Commit();
            }

            
return  list;

      这个例子中,我们用一个枚举DBSourceType来标志多个数据源,例子从标志位Basic的数据源的Slave库中读取所有的Student列表信息。

      接下来,我们来看对隔离级别的支持。

      还是使用上面的这个例子,假设我们的业务允许读取Student列表可以为脏读,那么可以降低读取的隔离级别(默认为ReadCommitted): 

            IList < Student >  list  =   null ;
            TransactionScopeFactory factory 
=   this .transactionScopeFactoryProvider.GetFactory(DBSourceType.Basic,  false );
            
using  (TransactionScope scope  =  factory.NewTransactionScope( false, IsolationLevel.ReadUncommitted))
            {
                IOrmAccesser
< Student >  accesser  =  scope.NewOrmAccesser < Student > ();
                list 
=  accesser.GetAll();
                scope.Commit();
            }

            
return  list;

      IsolationLevel定义如下:

 

    public   enum  IsolationLevel
    {
        ReadUncommitted 
=   0  ,
        ReadCommitted,
        RepeatableRead,      
        Serializable
    }

 

      DataRabbit3.3及以上版本对上述策略都给予了充分的支持,你可以下载最新版本试试。

      关于DataRabbit的更多信息目录,参见这里

 

目录
相关文章
ly~
|
1月前
|
数据库 数据库管理
数据库的事务处理机制有哪些优点?
数据库的事务处理机制具备多种优势:首先,它能确保数据一致性,通过原子性保证所有操作全成功或全失败,利用完整性约束维护数据的有效性;其次,增强了系统可靠性,提供故障恢复能力和正确处理并发操作的功能;最后,简化了应用程序开发工作,将操作封装为逻辑单元并集中处理错误,降低了开发复杂度。
ly~
30 1
|
6月前
|
缓存 NoSQL 关系型数据库
tp框架事务处理实例和理解
tp框架事务处理实例和理解
167 0
|
Oracle 关系型数据库 MySQL
分布式数据库事务 | 学习笔记
快速学习 分布式数据库事务
115 0
|
NoSQL 前端开发 Go
深入解析cassandra 轻量级事务原理
how to use cassandra是一个无主架构,多个node可以并行写,但并发场景下对于先读后写的操作,数据会有正确性问题。从cassandra2 开始提供轻量级事务支持,用于cas更新。使用示例: cqlsh> UPDATE cycling.cyclist_name SET firstname = ‘Roxane’ WHERE id = 4647f6d3-7bd2-4085-8d6c-1229351b5498 IF firstname = ‘Roxxane’; 这其实是一个标准的compare and swap 示例。
3250 0
|
数据库 关系型数据库 Oracle
[分布式]事务处理的常见方法
处理事务的常见方法有排队法、排他锁、读写锁、MVCC等方式。 排队法         事务处理中最重要也是最简单的方案是排队法,单线程地处理一堆数据。 在Redis中,如果数据全部在内存中,那么单线程处理所有Put、Get操作效率最高。
1291 0
|
测试技术
AntData.ORM框架 之 读写分离
环境准备 准备2台机器配置好Master Slaver模式 我是用vmware 2台虚拟机配置的。有需要请联系。 Master:192.168.11.130 Slaver:192.168.11.
1022 0
|
Java 中间件 关系型数据库
在应用层通过spring特性解决数据库读写分离
在应用层通过spring特性解决数据库读写分离    如何配置mysql数据库的主从? 单机配置mysql主从:http://my.oschina.net/god/blog/496   常见的解决数据库读写分离有两种方案 1、应用层 http://neoremind.net/2011/06/spring实现数据库读写分离 目前的一些解决方案需要在程序中手动指定数据源,比较麻烦,后边我会通过AOP思想来解决这个问题。
1320 0
|
SQL Oracle 关系型数据库
浅尝数据库并发控制
        数据库是一个共享资源,可以供多个用户使用。然而,对于大多数程序员来说,单处理机系统是我们接触最多的系统,运行在其上的数据库事务也并非真正意义上的并行,实际上它是这些并行事务的并行操作轮流交叉运行,这种并行执行方式称为交叉并发方式(Interleaved Concurrency),这样可以减少处理机的空闲时间,提高系统的效率。而在多处理机系统中,每个处理机可以运行一个事务,多
1681 0
|
.NET 开发框架 SQL
DataRabbit 轻量的数据访问框架(15)-- IOrmAccesser的BatchInsert批量插入!
DataRabbit3.0为ORM访问器提供了批量插入的功能,其方法定义如下:         ///         /// BatchInsert 批量插入一组记录。忽略所有Blob字段。        ///                void BatchInsert(IList entityList);     当我们需要一次性向同一Table中插入大量(如千条以上)的记录时,使用BatchInsert方法可以显著的提供性能。
825 0