public class IdGenerator : RedisToolBase
{
//redis客户端对象
private static readonly NedisClient client = new NedisClient(GetRedisConfig(redisConfigKey)); //redis客户端对象配置存放在Consul服务端的key
private static readonly string redisConfigKey = "redis/common/idgeneratorconfig"; private static readonly object objMaxIdsLock = new object();
// 存放BusinessIdKey,MaxId
private static readonly Dictionary<string, long> maxIds = new Dictionary<string, long>(); private static readonly object objNextIdsLock = new object();
// 存放BusinessIdKey,NextId
private static readonly Dictionary<string, long> nextIds = new Dictionary<string, long>(); private static readonly object objIncrementsLock = new object();
// 存放BusinessIdKey,id增量
private static readonly Dictionary<string, long> increments = new Dictionary<string, long>(); /// <summary>
/// 计算主键时的增量
/// </summary>
private static readonly uint persistenceIncrement = 10; /// <summary>
/// 业务IdKey
/// </summary>
private string busnessIdKey = string.Empty; /// <summary>
/// 使用业务ID的key,ID增量初始化
/// </summary>
/// <param name="BusnessIdKey">业务IdKey</param>
/// <param name="Increment">id增量,默认为1,不能大于10</param>
public IdGenerator(string BusinessIdKey, uint Increment=1)
{
Init(BusinessIdKey, Increment);
} /// <summary>
/// 初始化increments,maxIds,nextIds字典
/// </summary>
/// <param name="BusinessIdKey"></param>
/// <param name="Increment"></param>
private void Init(string BusinessIdKey,long Increment)
{
if (!increments.ContainsKey(BusinessIdKey))
{
lock (objIncrementsLock)
{
if (!increments.ContainsKey(BusinessIdKey))
{
increments.Add(BusinessIdKey, Increment);
}
}
}
if (!maxIds.ContainsKey(BusinessIdKey))
{
lock (objMaxIdsLock)
{
if (!maxIds.ContainsKey(BusinessIdKey))
{
maxIds.Add(BusinessIdKey, client.Increment(BusinessIdKey, persistenceIncrement));
}
}
}
if (!nextIds.ContainsKey(BusinessIdKey))
{
lock (objNextIdsLock)
{
if (!nextIds.ContainsKey(BusinessIdKey))
{
nextIds.Add(BusinessIdKey, maxIds[BusinessIdKey] - persistenceIncrement);
}
}
}
} /// <summary>
/// 重新设置MaxID
/// </summary>
/// <returns></returns>
private static void ResetMaxID(string BusinessIdKey)
{
maxIds[BusinessIdKey] = client.Increment(BusinessIdKey, persistenceIncrement);
nextIds[BusinessIdKey] = maxIds[BusinessIdKey] - persistenceIncrement;
} // 获取下一个ID的锁
private static readonly object nextIDLocker = new object(); /// <summary>
/// 根据业务Id键获取下一个主键ID
/// </summary>
/// <returns></returns>
public Int64 GetNextID(string BusinessIdKey)
{
lock (nextIDLocker)
{
nextIds[BusinessIdKey] = nextIds[BusinessIdKey] + 1; // 如果自增后的ID大于已经持久的ID,则先持久ID,再返回
if (nextIds[BusinessIdKey] >= maxIds[BusinessIdKey])
{
ResetMaxID(BusinessIdKey);
} return nextIds[BusinessIdKey];
}
}
}

  

1.IdGenerator使用说明:
var primaryKey = new IdGenerator("blog_id", 1);
var id = primaryKey.GetNextID("blog_id");

redisTools-IdGenerator的更多相关文章

  1. 流程开发Activiti 与SpringMVC整合实例

    流程(Activiti) 流程是完成一系列有序动作的概述.每一个节点动作的结果将对后面的具体操作步骤产生影响.信息化系统中流程的功能完全等同于纸上办公的层级审批,尤其在oa系统中各类电子流提现较为明显 ...

  2. Parallel并行之乱用

    关于Parallel我也不细说了,一则微软封装的很好用,二来介绍这个的遍地都是. 我要说的是,要想成为一个优秀的标题党,一定要把重点放到别的地方,为了节省大家阅读时间,我先把结论说了,然后再慢慢从头说 ...

  3. 一步步学习 Spring Data 系列之JPA(一)

    引入: Spring Data是SpringSource基金会下的一个用于简化数据库访问,并支持云服务的开源框架.其主要目标是使得数据库的访问变得方便快捷,并支持map-reduce框架和云计算数据服 ...

  4. 【DWR系列04】- DWR配置详解

    table { margin-left: 30px; width: 90%; border: 1px; border-collapse: collapse } img { border: 1px so ...

  5. YbSoftwareFactory 代码生成插件【十五】:Show 一下最新的动态属性扩展功能与键值生成器功能

    YbSoftwareFactory 各种插件的基础类库中又新增了两个方便易用的功能:动态属性扩展与键值生成器,本章将分别介绍这两个非常方便的组件. 一.动态属性扩展 在实际的开发过程中,你肯定会遇到数 ...

  6. Extjs 源码组成(4.0.7)

    (function(){})()形式的自执行,构建Ext对象(0~584) 1  设置全局对象EXt:global.Ext = {}, 2 实现了Ext对象面向对象编程的基础方法,如,apply,ex ...

  7. 关于Spring注解

    * @author 小郑 1        * @content ejb3注解的API定义在javax.persistence.*包里面. 2        * 注释说明: 3        * @E ...

  8. 自增长主键Id的另类设计

    一.引言 在使用ORM框架时,一个表有一个主键是必须的,如果没有主键,就没有办法来唯一的更新一条记录.在Sql Server数据库和Mysql数据库设置自增长的主键是一件很轻松的事情,如果在Oracl ...

  9. MyBatis的应用

    a)首先先导入固定的jar包 b)添加mybatis配置文件mybatis-config.xml 1.添加mybatis配置文件mybatis-config.xml <?xml version= ...

  10. 习课的视频播放器 video.js

    jsp <%@ page language="java" contentType="text/html; charset=utf-8" pageEncod ...

随机推荐

  1. pygame绘制文本

    def drawText(self,text,posx,posy,textHeight=48,fontColor=(0,0,0),backgroudColor=(255,255,255)): font ...

  2. 【Unity笔记】鼠标射线由指定层接收

    LayerMask mask = << LayerMask.NameToLayer("UI"); Ray ray = Camera.main.ScreenPointTo ...

  3. JavaScrip——练习(做悬浮框)

    通过HTML.CSS.JSP来实现 1.首先确定通过div嵌套来实现: 大的div里放默认显示的一层,限制其总层次高,设置超出部分隐藏 小的div里放鼠标移过去时显示的一层:3行1列的表格 1.1.什 ...

  4. java方法——重载2

    什么是Java方法重载 方法重载的定义 1 对于同一个类,如果这个类里面有两个或者多个重名的方法,但是方法的参数个数.类型.顺序至少有一个不一样,这时候局构成方法重载. END 方法重载示例 1 pu ...

  5. 轻量级ORM框架Dapper应用二:使用Dapper实现CURD操作

    在上一篇文章中,讲解了如何安装Dapper,这篇文章中将会讲解如何使用Dapper使用CURD操作. 例子中使用到的实体类定义如下: using System; using System.Collec ...

  6. xshell用ssh连接VMware中的ubuntu

    SSH分客户端openssh-client和openssh-server如果你只是想登陆别的机器的SSH只需要安装openssh-client(ubuntu有默认安装,如果没有则sudo apt-ge ...

  7. laravel 5.1 性能优化对比 - 框架提供的方法

    写了一个项目发现性能不如人意. 于是便测试下, 看下性能瓶颈在什么地方. 使用 ab -n 20 http://www.lartest.com/ 软件环境: OS : windows 8.1 CPU: ...

  8. EMS快递单号生成算法

    <?php function emsnum($ems, $num) { $fri = substr($ems, 2, 8); $head = substr($ems, 0, 2); $tail ...

  9. Semi-Supervised Classification with Graph Convolutional Networks

    Kipf, Thomas N., and Max Welling. "Semi-supervised classification with graph convolutional netw ...

  10. Docker之删除container和image

    删除所有停止的container: docker rm $(docker ps -a -q) 删除所有未标记的image docker rmi $(docker images | grep " ...