生成唯一號:思路,根據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;