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 ...
随机推荐
- Testlink1.9.17使用方法(第一章 前言)
第一章 前言 QQ交流群:585499566 一.Testlink主要功能: 测试项目管理 测试需求管理 测试用例管理 测试计划的制定 测试用例对测试需求的覆盖管理 测试用例的执行 大量测试数据的度量 ...
- IntelliJ IDEA常用快捷键(一)
Ctrl+J 键常用的组合 psvm:public static void main(String[] args) { } Serr: System.err.println("") ...
- 我喜欢的vs+va快捷键
拿到新版的vs,我首先会安装va,然后自定义快捷键.现在有些快捷键被系统占用,可以先remove掉,然后换成自己熟悉的快捷键.需要做到常用快捷键两个按键即可. alt+Q:文件中查询,复杂查询 ctr ...
- Oracle的实例恢复解析
在数据库服务器异常断电重启后,数据库会进行实例恢复,那么实例恢复的过程中Oracle做了什么操作呢?参考官网在这里做一下解释,菜鸟水平有限,欢迎勘正. 首先说下实例恢复的定义: Instance re ...
- [Hive_11] Hive 的高级聚合函数
0. 说明 Hive 的高级聚合函数 union all | grouping sets | cube | rollup pv //page view 页面访问量 uv //user view 访问人 ...
- Eric Chen Mock Interview
Given an array with integers. Find two non-overlapping subarrays A and B, which |SUM(A) - SUM(B)| is ...
- CISCO静态路由配置
静态路由:手动添加路由条目到路由表中 优点:没有额外的路由cpu负担,节约带宽,增加网络安全性. 缺点:必须去了解整个拓扑结构,如果网络拓扑发生变化,需要在所有r路由上手动修改路由表. 实验拓扑如下: ...
- DB2常见错误信息
000 00000 SQL语句成功完成01xxx SQL语句成功完成,但是有警告+012 01545 未限定的列名被解释为一个有相互联系的引用+098 01568 动态SQL语句用分号结束+100 0 ...
- Windows10反安装报错error code 2502 2503
先找系统TEMP目录,一般为C:\windows\temp,打开这个目录的权限,为这个目录中的User用户添加权限为完全控制,现在再反安装就不会报错了. 注:原因就是因为系统运行时需要用到临时文件的目 ...
- A - 畅通工程续 最短路
某省自从实行了很多年的畅通工程计划后,终于修建了很多路.不过路多了也不好,每次要从一个城镇到另一个城镇时,都有许多种道路方案可以选择,而某些方案要比另一些方案行走的距离要短很多.这让行人很困扰. 现在 ...