例如流水號格式如下:xx201604120001,2位字首加8位日期加4位流水號
首先各種搜尋出現如下解決方案
public class serialnohelper0001";
var date = serialno.substring(2, 8);
if (date == today)";}
return $"xx0001";
}}
然後測試
class program);}//等待執行完成
task.waitall(tasks);
console.writeline("-----------------------------------分割線-----------------------------------");
//測試是否重複
var repeat = array.groupby(m => m).where(m => m.count() > 1).select(m => m.key).tolist();
foreach (var item in repeat)
console.writeline(item);
console.readline();
}}
測試後不難發現,在高併發下很容易就出現重複。
好像**不對啊,修改serialnohelper類實現單例,然後給generate方法加鎖。這下應該可以了吧。
public sealed class serialnohelperpublic static serialnohelper helper
}return helper;}}
/// /// 生成流水號
///
/// 從資料庫讀取最大的流水號
///
public string generate(string serialno)
0001";
var date = serialno.substring(2, 8);
if (date == today)";}
return $"xx0001";}}
}
心情忐忑的按下f5,wtf,居然還是有重複。
不慌,走到視窗猛吸兩口霧霾壓壓驚。接下來分析一下為什麼還是會出現重複呢?
生成序列號的時候依賴的是從資料庫獲取最大的流水號,但是在生成序列號之後,到儲存序列號到資料庫這之間一般會有一些邏輯操作。
這就導致在高併發的時候,前乙個流水號還沒有儲存到資料庫,那就有可能從資料庫獲取到的流水號是相同的,那麼生成的流水號自然就會出現重複。
怎麼解決這個問題呢?在generate方法內就把生成的流水號儲存到資料庫?這顯然不太合適,上面提到儲存流水號到資料庫一般會有一些邏輯操作。
最終版本
public sealed class serialnohelperpublic static serialnohelper helper
}return helper;}}
/// /// 生成流水號
///
/// 從資料庫讀取最大的流水號
///
public string generate(string serialno)
";lastdate = today;
lastno = 0;
if (!string.isnullorempty(serialno) && serialno.substring(2, 8) == today)
lastno = convert.toint32(serialno.substring(10));
return $"xx";}}
}
終於成功了。
當然這種處理方式也有不好的地方。
比如當生成流水號最終沒有使用,會造成浪費。
最後
mysql 生成流水號 儲存過程 訂單編號
用儲存過程生成流水號是很常用的,這裡以生成訂單編號的流水號作為示例。新的一天的流水號從1開始,如 今天的訂單編號是cd20130109 00014,下乙個訂單編號將是cd20130109 00015 明天的訂單編號將從cd20130110 00001開始 生成規則 2位字首 年月日 5位流水號 或者...
SQL生成流水號
經過了幾次的測試終於成功了 declare year int,month int,day int,temp no varchar 12 needno varchar 4 no varchar 20 number varchar 50 randno varchar 50 nu varchar 10 s...
php生成流水號
function createn i else if i 100 else if i 1000 else echo substr 2012050010 0,6 echo createn 2 2 echo createn 9 9 echo createn 10 10 echo createn 11 1...