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 ...
随机推荐
- OneAPM 重磅登陆 CTDC 2018展示“ AIOps 双雄”创新实力
9月7日-8日,以“AI 智享未来”为主题的2018第二届 CTDC 首席技术官领袖峰会在乌镇盛大召开,大会由 CTOA 首席技术官领袖联盟.ITShare 主办,大会邀请了国内外顶级互联网.在线教育 ...
- python使用sax实现xml解析
之前在使用xml解析的时候,在网上搜了很多教程,最终没有能按照网上的教程实现需求. 所以呢,只好自己去看源码,在sax的__init__.py下看到这么一段代码: 1 def parse(source ...
- OSWatcher使用过程中小问题解决方法
本文介绍一下在使用OSWatcher过程当中遇到的两个问题的解决方法.如有更好的方法,敬请留言. 1:OSWatcher在配置文件里面设置了参数OSW_COMPRESSION为gzip后,OSWatc ...
- CSS margin 外边距 属性的位置关系
padding:内边距 margin :外边距 margin:10px; 所有 4 个外边距都是 10px ******************************************* ma ...
- SQL Server 锁实验(UPDATE加锁探究)
update语句: 本例中由于看到的是update执行完的锁情况,因此无法看到IU锁,但其实针对要修改的数据页和索引页会先加IU锁,记录和键先加U锁,然后再转化为IX和X锁. 如果想要看到IU锁和U锁 ...
- EF Code First列名 'Discriminator' 无效的问题
新建了一个类继承EF Model类,运行报错 EF Code First列名 'Discriminator' 无效 EF会把项目中在DbContext中引用的所有的Model类及这些Model类对应 ...
- c/c++ 模板与STL小例子系列<三> traits
c/c++ 模板与STL小例子系列 traits 对这个概念,还是处于懵逼的状态,初步体会就是,为了解决类型之间的转换问题. 从一个类型为A的指针,转化到类型为B的指针,中间需要用void*来作为中介 ...
- 查看iPhone电池寿命
iBackupBot 软件:iBackupBot for iTunes (收费软件) 官网:http://www.icopybot.com/download.htm iBackupBot for iT ...
- Java的基础知识二
一.方法函数 函数也称为方法,就是定义在类中的具有特定功能的一段独立代码.用于定义功能,提高代码的复用性. 函数的特点1> 定义函数可以将功能代码进行封装,便于对该功能进行复用:2> 函数 ...
- LeetCode算法题-Balanced Binary Tree(Java实现)
这是悦乐书的第167次更新,第169篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第26题(顺位题号是110).给定二叉树,判断它是否是高度平衡的.对于此问题,高度平衡二 ...