今天抽了点时间,写了一个通用的生成编号的程序!

我的生成规则为年月日+两位编号,即:yyyyMMdd+两位编号,譬如:2018101001 / 2018101002 / 2018101003

首先,一个项目中有很多表需要生成编号,譬如:产品编号,评估编号,学生学号等

下面看看我的思路,如下:

首先创建一张表,如下:

create table CM_CodeNo
(
Id int identity(1,1) primary key not null,
CodeCate varchar(50) not null unique,--现场考察 非设计类履约评估等
VersionNum TimeStamp not null,
CodeYear int,
CodeMonth int,
CodeDay int,
CodeValue varchar(20),
CodeCount int,
AddTime datetime default(getdate()),
)

简单解读下这张表的构造:

CodeCate:编号分类,譬如:产品编号、评估编号等

VersionNum:乐观锁版本号,用于处理并发,有兴趣的可参考鄙人的博客:https://www.cnblogs.com/chenwolong/p/BF.html#4094056

CodeYear:年

CodeMonth:月

CodeDay:日

CodeCount:代表今天生产了几个编号

AddTime:生产时间

CodeValue:无效字段,没用到...

表的解读就这么多,现在来看一组存储过程:

ALTER proc [dbo].[LockCodeNoProc] --
(
@CodeCate nvarchar(50),
@IsSuccess bit=0 output
)
as
declare @currentYear as int
declare @currentMonth as int
declare @currentDay as int
declare @count as int
declare @CodeCount as int
declare @flag as TimeStamp
declare @rowcount As int set @currentYear=DateName(year,GetDate())
set @currentMonth=DateName(month,GetDate())
set @currentDay=DateName(day,GetDate())
begin tran
select @count=count(1) from CM_Code where CodeYear=@currentYear and CodeMonth = @currentMonth and CodeDay=@currentDay and CodeCate=@CodeCate
if @count=0
begin
insert into CM_Code(CodeCate,CodeYear,CodeMonth,CodeDay,CodeValue,CodeCount,AddTime)
values(@CodeCate,@currentYear,@currentMonth,@currentDay,'',1,GETDATE())
select CodeCount from CM_Code where CodeYear=@currentYear and CodeMonth = @currentMonth and CodeDay=@currentDay and CodeCate=@CodeCate
end
else
begin
select @count=CodeCount,@flag=VersionNum from CM_Code where CodeYear=@currentYear and CodeMonth = @currentMonth and CodeDay=@currentDay and CodeCate=@CodeCate
--waitfor delay '00:00:10' --可用于模拟并发
update CM_Code set CodeCount=@count+1 where VersionNum=@flag and CodeYear=@currentYear and CodeMonth = @currentMonth and CodeDay=@currentDay and CodeCate=@CodeCate
set @rowcount=@@ROWCOUNT
select CodeCount from CM_Code where CodeYear=@currentYear and CodeMonth = @currentMonth and CodeDay=@currentDay and CodeCate=@CodeCate if @rowcount>0
begin
set @IsSuccess=1
select @IsSuccess
end
else
begin
set @IsSuccess=0
select @IsSuccess
end
end
commit tran

调用这个存储过程,会返回当前分类今天生产的编号数量,

时间有限,不作过多解读,大家自行理解,

下面是C#代码:

    public class GetCode
{
public static string GetCodeNo(Enum CodeCate)
{
PortalCodeModel M = new PortalCodeModel();
M = U_GetCode.GetCodeNo(CodeCate);
//--模拟发生了并发,需要等待,重复请求,最大请求次数为10次
int retry = ;
while (!M.IsSuccess && retry > )
{
retry--;
GetCodeNo(CodeCate);
}
//
string code = GetCodeString(M.Result);
return code; } public static string GetCodeString(int CodeCount)
{
string initStr = DateTime.Now.ToString("yyyyMMdd");
int initLen = initStr.Length;
int Len = CodeCount.ToString().Length;
int MaxLen = ;
string ling = string.Empty;
int TotalLen = initLen + Len;
if (TotalLen <= MaxLen)
{
switch (Len)
{
case :ling = initStr + "" + CodeCount.ToString();break;
default: ling = initStr + CodeCount.ToString(); break;
}
}
return ling;
}
}

DAL层如下:

        public static PortalCodeModel GetCodeNo(Enum CodeCate)
{
using (DataAccessBroker broker = DataAccessFactory.Instance())
{
PortalCodeModel M = new PortalCodeModel();
DataAccessParameterCollection parameters = new DataAccessParameterCollection();
parameters.AddWithValue("@CodeCate", CodeCate.ToString());
parameters.AddWithValue("@IsSuccess", ParameterDirection.ReturnValue); DataSet ds = broker.FillCommandDataSet("LockCodeNoProc", parameters);
//
if (ds != null && ds.Tables.Count > )
{
var Result = Convert.ToInt32(ds.Tables[].Rows[]["CodeCount"]);
var Bol = (ds.Tables[].Rows[][]).ToString();
if (Bol == "True")
{
M.Result = Result;
M.IsSuccess = true;
}
else
{
M.Result = Result;
M.IsSuccess = false;
}
}
return M;
}
}

枚举层如下:

    /// <summary>
/// 各个枚举的‘值’使用表名即可
/// </summary>
public enum CodeCateEnum
{
[Description("现场考察")]
Inspection,
[Description("非设计类过程评估")]
EvluationPros,
[Description("非设计类履约评估")]
EvluationPlan,
}

OK ,就这么多,太忙,就不做过多的演示了!

  public class PortalCodeModel
{
public bool IsSuccess { get; set; }
public int Result { get; set; }
}

说明下:当返回 IsSuccess 为 False 时,及说明发生了并发,应执行重复请求。这里采用的方式是:重复请求十次,直至成功为止!

C# 代码执行的时候,当第一次执行存储过程,会异常,请自行处理!

谢谢!

C# 生成编号(防并发)的更多相关文章

  1. EndNote在Word中插入文献不能自动生成编号 - 解决方案

    本文出处:新浪博客“小数码植物摄影”之http://blog.sina.com.cn/s/blog_629be3eb0100sih3.html 新浪博客“小数码植物摄影”首页:http://blog. ...

  2. sql语句单据编号生成防并发

    有用户反馈说发现重复单据号,检查发现以下单据号被分配给了不同的两个职工 系统中使用语句exec GetNewOrderNumber 'pwgnumber','PWG',1, @pwg_number o ...

  3. 【SQL-自动生成编号】按规则自动生成单据编号 以及并发问题_使用触发器、函数 等

    描述:每种单据新建时,自动生成它的单据编号. 规则如:固定码+日期+流水号 (ABC1603180001) 方法一:触发器 触发器的缺点是,执行了sql之后才看到编码. 测试:流水号不能超过最大数,否 ...

  4. C#生成编号

    //自动生成账单编号 public string GetNewPoID(string Prefix) { string NewPoID = Prefix + DateTime.Now.Year.ToS ...

  5. redis 初步认识四(redis锁,防并发)

    using System; namespace ConsoleAppRedis { class Program { static void Main(string[] args) { //第一种,无登 ...

  6. SQL SERVER 批量生成编号

    开始: 在testing中,为了模拟orders,有个要求给数据库dba,如何通过后台数据库脚本快速批量生成orders. 分析 站在数据库角度,批量生成orders,也就是批量生成表中的行数据. s ...

  7. 支付宝防并发方案之"一锁二判三更新"

    每年支付宝在双11和双12的活动中,都展示了绝佳的技术能力.这个能力不但体现在处理高TPS量的访问,更体现在几乎不会出错,不会出现重复支付的情况,那这个是怎么做到的呢? 诚然,为了实现在高并发下仍不会 ...

  8. 自动生成编号(B开头后跟6位,数据库查询不重复)

    private string GetAccountNo() { try { string shortName="B"; "; //查询数据库 7位且包含“B” & ...

  9. odoo之自动生成编号问题

    单独的seq.xml文件 <?xml version="1.0" encoding="utf-8"?><openerp> <dat ...

随机推荐

  1. redis cluster是如何做到集两家之长的

    站在读写分离的层次看redis的时候,redis和master和slave存在明显的主从关系,也就是说master处于管理状态,salve跟着大哥混,master给小弟slave发粮食[发送内存快照数 ...

  2. Android为TV端助力 转载:android MVC设计模式

    Controller控制器 import android.app.Dialog; import android.app.ProgressDialog; import android.os.Bundle ...

  3. java后台打开浏览器代码

    import java.awt.Desktop; import java.io.IOException; import java.net.URI; import java.net.URISyntaxE ...

  4. 第一次使用VS Code时你应该知道的一切配置

    前言 本文最新内容将在GitHub上实时更新. VS Code 本来是前端人员专用,但由于它实在是太好用了,于是,各种开发方向的码农也正在用 VS Code 作为他们的主力编程工具.甚至是一些写作的同 ...

  5. 【PHPStorm使用手册】php interpreter is not configured

    php interpreter is not configured 未配置php解析器 第一步: 引入下载好的php.exe 打开窗口 file -> settings -> Langua ...

  6. hive Caused by: java.lang.RuntimeException: Unable to instantiate org.apache.hadoop.hive.ql.metadata.SessionHiveMetaStoreClient

    Exception in thread "main" java.lang.RuntimeException: org.apache.hadoop.hive.ql.metadata. ...

  7. css属性总结

    前言 有些属性不是很常用,但是工作中遇到了,记录一下,方便学习. 1.text-indent text-indent 属性规定文本块中首行文本的缩进.主要实现就像word那种首行缩进的效果. 详解ht ...

  8. Leancloud+Valine打造Hexo个人博客极简评论系统

    以下配置是基于Next主题6.1.0版本 效果见个人博客的最下方评论. Leancloud配置 首先访问Leancloud官网https://leancloud.cn/ 有Github账号的小伙伴可以 ...

  9. 【算法】LeetCode算法题-Palindrome Number

    这是悦乐书的第144次更新,第146篇原创 今天这道题和回文有关,即从前往后和从后往前是一样的,如"上海自来水来自海上"就是一个回文字符串,如整数121就是回文数,这些都是和回文相 ...

  10. css点滴1—八种方式实现元素垂直居中

    这里介绍实现元素垂直居中的方式,文章是参考了<css制作水平垂直居中对齐>这一篇文章. 1.行高和高度实现 这种方式实现单行垂直居中是很简单的,但是要保证元素内容是单行的,并且其高度是不变 ...