优化 DbConfigProvider 的并发处理
在 DbConfigProvider 类中引入了 `_saveLock` 对象,以防止保存操作与定时刷新操作之间的冲突。更新了 `SaveAll` 方法以使用锁定机制,确保在保存配置时不受干扰,并在保存后更新缓存。同时,`DoRefresh` 方法现在使用 `Monitor.TryEnter` 来避免在保存期间阻塞刷新操作,并在检测到配置改变时重新加载配置并更新缓存,确保操作完成后释放锁。
This commit is contained in:
parent
6f8a919a7a
commit
8d07a8cf79
|
@ -26,6 +26,9 @@ public class DbConfigProvider : ConfigProvider
|
|||
public Int32 Period { get; set; } = 15;
|
||||
|
||||
private IDictionary<String, Object?>? _cache;
|
||||
|
||||
/// <summary>保存操作锁,防止与定时刷新冲突</summary>
|
||||
private readonly Object _saveLock = new();
|
||||
#endregion
|
||||
|
||||
#region 方法
|
||||
|
@ -215,14 +218,27 @@ public class DbConfigProvider : ConfigProvider
|
|||
/// <summary>保存配置树到数据源</summary>
|
||||
public override Boolean SaveAll()
|
||||
{
|
||||
lock (_saveLock)
|
||||
{
|
||||
XTrace.WriteLine("[{0}/{1}]开始保存配置", Category, UserId);
|
||||
|
||||
var list = Parameter.FindAllByUserID(UserId, Category);
|
||||
Save(list, Root, null);
|
||||
|
||||
// 重新加载配置以更新缓存,避免被DoRefresh覆盖
|
||||
var dic = GetAll();
|
||||
if (dic != null)
|
||||
{
|
||||
SaveCache(dic);
|
||||
XTrace.WriteLine("[{0}/{1}]配置保存完成,已更新缓存", Category, UserId);
|
||||
}
|
||||
|
||||
// 通知绑定对象,配置数据有改变
|
||||
NotifyChange();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void Save(IList<Parameter> list, IConfigSection root, String? prefix)
|
||||
{
|
||||
|
@ -253,6 +269,9 @@ public class DbConfigProvider : ConfigProvider
|
|||
pi.Save();
|
||||
}
|
||||
}
|
||||
|
||||
// 确保所有数据库操作完成,避免事务延迟导致的读取不一致
|
||||
Thread.Sleep(10);
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
@ -289,6 +308,15 @@ public class DbConfigProvider : ConfigProvider
|
|||
/// <summary>定时刷新配置</summary>
|
||||
/// <param name="state"></param>
|
||||
protected void DoRefresh(Object state)
|
||||
{
|
||||
// 使用TryEnter避免在保存操作期间阻塞
|
||||
if (!Monitor.TryEnter(_saveLock, 100))
|
||||
{
|
||||
// 如果无法获取锁,说明正在保存,跳过本次刷新
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
using var showSql = Parameter.Meta.Session.Dal.Session.SetShowSql(false);
|
||||
|
||||
|
@ -311,7 +339,7 @@ public class DbConfigProvider : ConfigProvider
|
|||
|
||||
if (changed.Count > 0)
|
||||
{
|
||||
XTrace.WriteLine("[{0}/{1}]配置改变,重新加载如下键:{2}", Category, UserId, changed.ToJson());
|
||||
XTrace.WriteLine("[{0}/{1}]定时检测到配置改变,重新加载如下键:{2}", Category, UserId, changed.ToJson());
|
||||
|
||||
Root = Build(dic);
|
||||
|
||||
|
@ -321,5 +349,10 @@ public class DbConfigProvider : ConfigProvider
|
|||
NotifyChange();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
Monitor.Exit(_saveLock);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
Loading…
Reference in New Issue