重寫信眾編號程式
This commit is contained in:
@@ -8,5 +8,5 @@ using System.Web;
|
||||
/// </summary>
|
||||
public static class GlobalVariables
|
||||
{
|
||||
public static readonly object FNumberLock = new object();
|
||||
// FNumberLock 已移除,因為改用資料庫直接取號,不再需要 Application 狀態鎖定
|
||||
}
|
||||
@@ -190,21 +190,87 @@ 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;
|
||||
}
|
||||
f_number += nextSerial.ToString("D5");
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 如果所有重試都失敗,使用時間戳記
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -27,8 +27,6 @@
|
||||
//GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear();
|
||||
//註冊自訂路由
|
||||
RouteConfig.RegisterRoutes(RouteTable.Routes);
|
||||
InitializeFNumberSerial();//啟動項目的時候查詢出信眾編號的最大值放在記憶體中
|
||||
|
||||
//bundle js、css
|
||||
//BundleConfig.RegisterBundles(BundleTable.Bundles);
|
||||
|
||||
@@ -63,38 +61,4 @@
|
||||
System.Web.HttpContext.Current.SetSessionStateBehavior(System.Web.SessionState.SessionStateBehavior.Required);
|
||||
}
|
||||
|
||||
private void InitializeFNumberSerial()
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var _db = new Model.ezEntities())
|
||||
{
|
||||
var maxFNumber = _db.followers
|
||||
.Where(m =>
|
||||
////m.IsDel == false && ////不確定是否新增欄位? 先註解
|
||||
m.f_number.Length == 14 &&
|
||||
(m.f_number.StartsWith("M") || m.f_number.StartsWith("F")))
|
||||
.OrderByDescending(m => m.reg_time)
|
||||
.Select(m => m.f_number)
|
||||
.FirstOrDefault();
|
||||
|
||||
int nextSerial = 0;
|
||||
if (!string.IsNullOrEmpty(maxFNumber))
|
||||
{
|
||||
try
|
||||
{
|
||||
var serialPart = maxFNumber.Substring(9, 5);
|
||||
nextSerial = int.Parse(serialPart);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
Application["FNumberSerial"] = nextSerial;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Application["FNumberSerial"] = 0;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -207,25 +207,8 @@ public partial class admin_follower_reg : MyWeb.config
|
||||
}
|
||||
}
|
||||
}
|
||||
// 使用新的 generate_f_number 方法,已內建重號檢查和重試機制
|
||||
followers.f_number = follower.generate_f_number(sex.SelectedValue);
|
||||
if (chk_pro_num(followers.f_number))
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
followers.f_number = follower.generate_f_number(sex.SelectedValue);
|
||||
if (chk_pro_num(followers.f_number))
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
L_msg.Type = alert_type.danger;
|
||||
L_msg.Text = "信眾編號重複";
|
||||
return;
|
||||
}
|
||||
}
|
||||
followers.identity_type = Val(identity_type.SelectedValue);
|
||||
if(!isStrNull(leader.Value)) followers.leader = Val(leader.Value);
|
||||
if (!isStrNull(country.Value)) followers.country = country.Value;
|
||||
|
||||
Reference in New Issue
Block a user