C# 生成编号(防并发)
今天抽了点时间,写了一个通用的生成编号的程序!
我的生成规则为年月日+两位编号,即: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# 生成编号(防并发)的更多相关文章
- EndNote在Word中插入文献不能自动生成编号 - 解决方案
本文出处:新浪博客“小数码植物摄影”之http://blog.sina.com.cn/s/blog_629be3eb0100sih3.html 新浪博客“小数码植物摄影”首页:http://blog. ...
- sql语句单据编号生成防并发
有用户反馈说发现重复单据号,检查发现以下单据号被分配给了不同的两个职工 系统中使用语句exec GetNewOrderNumber 'pwgnumber','PWG',1, @pwg_number o ...
- 【SQL-自动生成编号】按规则自动生成单据编号 以及并发问题_使用触发器、函数 等
描述:每种单据新建时,自动生成它的单据编号. 规则如:固定码+日期+流水号 (ABC1603180001) 方法一:触发器 触发器的缺点是,执行了sql之后才看到编码. 测试:流水号不能超过最大数,否 ...
- C#生成编号
//自动生成账单编号 public string GetNewPoID(string Prefix) { string NewPoID = Prefix + DateTime.Now.Year.ToS ...
- redis 初步认识四(redis锁,防并发)
using System; namespace ConsoleAppRedis { class Program { static void Main(string[] args) { //第一种,无登 ...
- SQL SERVER 批量生成编号
开始: 在testing中,为了模拟orders,有个要求给数据库dba,如何通过后台数据库脚本快速批量生成orders. 分析 站在数据库角度,批量生成orders,也就是批量生成表中的行数据. s ...
- 支付宝防并发方案之"一锁二判三更新"
每年支付宝在双11和双12的活动中,都展示了绝佳的技术能力.这个能力不但体现在处理高TPS量的访问,更体现在几乎不会出错,不会出现重复支付的情况,那这个是怎么做到的呢? 诚然,为了实现在高并发下仍不会 ...
- 自动生成编号(B开头后跟6位,数据库查询不重复)
private string GetAccountNo() { try { string shortName="B"; "; //查询数据库 7位且包含“B” & ...
- odoo之自动生成编号问题
单独的seq.xml文件 <?xml version="1.0" encoding="utf-8"?><openerp> <dat ...
随机推荐
- Python sax模块(SAX解析XML)
XML样例: <?xml version="1.0"?> <collection shelf="New Arrivals"> <m ...
- python 数据驱动ddt使用,需要调用下面的代码,请挨个方法调试,把不用的注释掉
#!/usr/bin/env/python # -*- coding: utf-8 -*- # @Time : 2018/12/15 15:27 # @Author : ChenAdong # @Em ...
- Java-- String源码分析
版权声明:本文为博主原创文章,未经博主允许不得转载 本篇博文基于java8,主要探讨java中的String源码. 首先,将一个类分为几个部分,分别是类定义(继承,实现接口等),全局变量,方法,内部类 ...
- springmvc复习笔记----springmvc姓名年龄例子:RequestParam 试水
继续 继上节http://www.cnblogs.com/tk55/p/6652394.html 重要部分颜色突出 结构 包 web.xml 乱码处理方面设置 <url-pattern>* ...
- 初识kafka
简介 Kafka经常用于实时流数据架构,用于提供实时分析.本篇将会简单介绍kafka以及它为什么能够广泛应用. kafka的增长是爆炸性的.2017年超过三分之一的世界五百强公司在使用kafk ...
- Mybatis 学习---${ }与#{ }获取输入参数的区别、Foreach的用法
一.Mybatis中用#{}和${}获取输入参数的区别 1.“#{}“和“${}”都可以从接口输入中的map对象或者pojo对象中获取输入的参数值.例如 <mapper namespace=&q ...
- ASP.NET -- 一般处理程序ashx
ASP.NET -- 一般处理程序ashx 如果在一个html页面向服务器端请求数据,可用ashx作为后台页面处理数据.ashx适合用作数据后台处理,相当于WebForm中的aspx.cs文件或 ...
- LeetCode算法题-Factorial Trailing Zeroes(Java实现)
这是悦乐书的第183次更新,第185篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第42题(顺位题号是172).给定一个整数n,返回n!中的尾随零数.例如: 输入:3 输 ...
- Docker: dockerfile常用关键字
Dockerfile指令 Dockfile执行和shell命令一行,一行一行执行- 写Dockerfile注意点: 1. 尽量少RUN 2. 多个命令拼接在一起 ...
- WebAPI HelpPage支持Area
WebAPI原生的HelpPage文档并不支持Area的生成,需进行如下改造: WebApiConfig: public static class WebApiConfig { public stat ...