HTML5技术

通用的序列号生成器库 - 张善友

字号+ 作者:H5之家 来源:博客园 2016-02-05 08:42 我要评论( )

正如文章《 通用的业务编号规则设计实现(附源码) 》 文章里需要一个多实例和线程安全的序列化生成器,在SQL Server 2012+ 版本 有一个通过.NET程序集的序列号transact-sql 函数 。 这篇文章向大家介绍一个使用SQL Server 和Sql Azure 以及Mongodb 实现的序

正如文章《通用的业务编号规则设计实现(附源码)》 文章里需要一个多实例和线程安全的序列化生成器,在SQL Server 2012+ 版本 有一个通过.NET程序集的序列号transact-sql 函数 。 这篇文章向大家介绍一个使用SQL Server 和Sql Azure 以及Mongodb 实现的序列号生成器。

 

在Github上有个项目 https://github.com/getAddress/Sequence ,我Fork了一份,增加了一个Mongodb 实现,地址是https://github.com/geffzhang/Sequence。下面我介绍下使用Mongodb实现的sequence 存储,主要就是实现接口IstateStore

 

这里实现的关键点就是在更新数据的时候如何保证原子性的操作,Mongo 可以使用findAndModify命令, findAndModify可以从数据库查找返回一个文档的同时更新/插入/删除文档,原子操作,线程安全,功能强大,原型复杂。

 

public async Task<bool> UpdateAsync(SequenceKey sequenceKey, ISequence sequence)

{

var sequenceEntity = sequence as Sequences;

sequenceEntity.Id = sequenceKey.Value;

 

var query = Query.And(Query.EQ("_id", ObjectId.Parse(sequenceKey.Value)));

var update = MongoDB.Driver.Builders.Update < Sequences>.Set( c => c.CurrentValue , sequenceEntity.CurrentValue);

 

var updatedSequenceEntity = this.Collection.FindAndModify(new FindAndModifyArgs() { Query = query, Update = update, VersionReturned = FindAndModifyDocumentVersion.Original, SortBy = null });

var doc = updatedSequenceEntity.ModifiedDocument;

return doc != null;

 

}

findAndModify命令中每个键对应的值如下所示。

findAndModify 字符窜,集合名。

query 查询文档,用来检索文档的条件。

sort 排序结果的条件。

update 修改器文档,对所找到的文档执行的更新。

remove 布尔类型,表示是否删除文档。

new 布尔类型,表示返回的是更新前的文档还是更新后的文档。默认是更新前的文档。

"update"和"remove"必须有一个,也只能有一个。要是匹配不到文档,这个命令会返回一个错误。

 

这个命令有些限制。它一次只能处理一个文档,也不能执行upsert操作,只能更新已有文档。

相比普通更新来说,findAndModify速度要慢一些。大概耗时相当于一次查找,一次更新和一次getLastError顺序执行所需的时间。

 

使用起来非常简单,下面我们使用Mongodb 作为代码示例:

通过Nuget 安装getAddress.Sequence.Mongo:

 

  • 根据业务需求创建一个序列化生成器,也就是SequenceKey ,Mongo 使用它的ObjectId 来作为Key

  • var stateProvider = GetStateProvider();

    var sequenceGenerator = new SequenceGenerator(stateProvider);

    var sequence = await CreateSequence(stateProvider,increment: 0, startAt: 5);

    var sequenceKey = await stateProvider.AddAsync(sequence);

     

  • 使用这个SequenceKey 就可以用调用了

  •     var stateProvider = GetStateProvider();

    var sequenceGenerator = new SequenceGenerator(stateProvider);

    var nextValue1 = await sequenceGenerator.NextAsync(new SequenceKey { Value = "56af206c7c2a5827389ad412"});

    项目里有完整的单元测试用例,跑完整个单元测试用例,Mongodb的数据展示一下:

    我们把数据存储在一个叫做Sequences的Collection里,_id 列就是我们的sequenceKey。StartAt 表示起点, Increment 表示步长, MaxValue 表示最大值, MinValue 表示最小值,Cycle 表示达到最大值,从头开始循环,CurrentValue 表示当前值。

     

    1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

    相关文章
    • [移动端] IOS下border-image不起作用的解决办法 - 小路_同学

      [移动端] IOS下border-image不起作用的解决办法 - 小路_同学

      2017-05-02 12:04

    • 【react学习】关于react框架使用的一些细节要点的思考 - 外婆的彭湖湾

      【react学习】关于react框架使用的一些细节要点的思考 - 外婆的彭湖

      2017-04-16 18:00

    • CSS 几款比较常用的翻转特效 - 周全535201285

      CSS 几款比较常用的翻转特效 - 周全535201285

      2017-02-06 16:00

    • 不常见但很有用的chrome调试工具使用方法 - 小火柴的蓝色理想

      不常见但很有用的chrome调试工具使用方法 - 小火柴的蓝色理想

      2017-01-24 14:00

    网友点评
    <