重寫信眾編號程式

This commit is contained in:
2025-09-10 00:21:47 +08:00
parent e6c6b1f43f
commit 05a7cc3e9b
4 changed files with 78 additions and 65 deletions

View File

@@ -190,20 +190,86 @@ namespace Model
public static string generate_f_number(string sex = "男眾")
{
string selectedSex = sex;
string f_number = selectedSex == "男眾" ? "M" : "F";
var datePart = DateTime.Now.ToString("yyyyMMdd");
f_number += datePart;
int nextSerial = 1;
lock (GlobalVariables.FNumberLock)
// 使用重試機制確保不重號
int maxRetries = 5;
for (int retry = 0; retry < maxRetries; retry++)
{
nextSerial = (int)HttpContext.Current.Application["FNumberSerial"] + 1;
HttpContext.Current.Application["FNumberSerial"] = nextSerial;
try
{
using (var _db = new Model.ezEntities())
using (var transaction = _db.Database.BeginTransaction())
{
// 在交易中查詢最大序號
int nextSerial = GetNextSerialFromDatabase(_db, datePart, selectedSex);
string f_number = GenerateFNumber(selectedSex, datePart, nextSerial);
// 立即檢查是否重複(在交易中)
if (!_db.followers.Any(f => f.f_number == f_number))
{
transaction.Commit();
return f_number;
}
// 如果重複,回滾交易並重試
transaction.Rollback();
// 短暫延遲後重試
if (retry < maxRetries - 1)
{
System.Threading.Thread.Sleep(10 + retry * 5); // 10ms, 15ms, 20ms, 25ms
}
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"生成編號失敗 (重試 {retry + 1}): {ex.Message}");
if (retry == maxRetries - 1)
{
// 最後一次重試失敗,使用時間戳記確保唯一性
return GenerateFNumberWithTimestamp(selectedSex, datePart);
}
}
}
f_number += nextSerial.ToString("D5");
return f_number;
// 如果所有重試都失敗,使用時間戳記
return GenerateFNumberWithTimestamp(selectedSex, datePart);
}
private static int GetNextSerialFromDatabase(Model.ezEntities _db, string datePart, string sex)
{
var prefix = sex == "男眾" ? "M" : "F";
var searchPattern = prefix + datePart;
var maxFNumber = _db.followers
.Where(m =>
m.f_number.Length == 14 &&
m.f_number.StartsWith(searchPattern))
.OrderByDescending(m => m.f_number)
.Select(m => m.f_number)
.FirstOrDefault();
if (!string.IsNullOrEmpty(maxFNumber))
{
var serialPart = maxFNumber.Substring(9, 5);
return int.Parse(serialPart) + 1;
}
return 1;
}
private static string GenerateFNumber(string sex, string datePart, int serial)
{
string prefix = sex == "男眾" ? "M" : "F";
return prefix + datePart + serial.ToString("D5");
}
private static string GenerateFNumberWithTimestamp(string sex, string datePart)
{
// 使用時間戳記確保唯一性(最後手段)
string prefix = sex == "男眾" ? "M" : "F";
var timestamp = DateTime.Now.ToString("HHmmss");
return prefix + datePart + timestamp;
}
}