C# 生成系统唯一号
生成唯一号:思路,根据yymmddhhmmss+自增长号+唯一服务器号( SystemNo)生成唯一码,总长度19,例如:1509281204550000101.
public
class
UniqueNumber
{
private
static
long
num = 0;
//流水号
private
static
object
lockObj =
new
object
();
//锁
/// <summary>
/// 生成自增长码
/// </summary>
/// <returns></returns>
private
static
long
GenerateUniqueNumber()
{
lock
(lockObj)
//加锁
{
num = num + 1;
num = (num == 100000 ? 1 : num);
//如果大于10W则从零开始,由于一台服务器一秒内不太可能有10W并发,所以yymmddhhmmss+num是唯一号。yymmddhhmmss+num+SystemNo针对多台服务器也是唯一号。
}
return
num;
}
/// <summary>
/// 获取唯一码
/// </summary>
/// <param name="SystemNo">系统号</param>
/// <returns>唯一码</returns>
public
static
long
GetUniqueNumber(
int
SystemNo)
{
if
(SystemNo > 99 || SystemNo < 1)
{
throw
new
Exception(
"系统号有误"
);
}
lock
(lockObj)
// 要使静态变量多并发下同步,需要两次加锁。
{
string
time = DateTime.Now.ToString(
"yyMMddHHmmss"
);
//12位;
return
long
.Parse(time + GenerateUniqueNumber().ToString().PadLeft(5,
'0'
) + SystemNo.ToString().PadLeft(2,
'0'
));
//19位
}
}
}
测试:
static
void
Main(
string
[] args)
{
for
(
int
i = 1; i < 98; i++)
//N个线程
{
Thread thread =
new
Thread(
new
ParameterizedThreadStart(Exe));
thread.Start(i);
}
}
public
static
void
Exe(
object
sysNo)
{
for
(
int
i = 0; i < 1000; i++)
//M次循环执行
{
long
v = UniqueNumber.GetUniqueNumber((
int
)sysNo);
DbHelperMySQL.ExecuteSql(
" insert into abacus.guidtest (val) values ('"
+ v +
"');"
);
}
}
mySQl脚本:
SELECT
*
FROM
abacus.guidtest;
select
count
(id)
from
abacus.guidtest;
select
val
from
abacus.guidtest
group
by
val
having
count
(val) >1;
truncate
table
abacus.guidtest;
CREATE
TABLE
`guidtest`
`id`
int
(11)
NOT
NULL
AUTO_INCREMENT,
`val`
bigint
(20)
NOT
NULL
,
PRIMARY
KEY
(`id`),
UNIQUE
KEY
`id_UNIQUE` (`id`)
) ENGINE=InnoDB
DEFAULT
CHARSET=utf8;