Add new optimistic lock

This commit is contained in:
sunkaixuan
2022-07-24 16:39:29 +08:00
parent 675a10cdeb
commit 91ee5d1d0e
3 changed files with 64 additions and 1 deletions

View File

@@ -59,6 +59,15 @@ namespace SqlSugar
var sqlObj = this.ToSql();
this.Context.Queues.Add(sqlObj.Key, sqlObj.Value);
}
public virtual int ExecuteCommandWithOptLock()
{
var updateData = UpdateObjs.FirstOrDefault();
if (updateData == null) return 0;
_ExecuteCommandWithOptLock(updateData);
return this.ExecuteCommand();
}
public virtual int ExecuteCommand()
{
string sql = _ExecuteCommand();
@@ -74,6 +83,13 @@ namespace SqlSugar
{
return this.ExecuteCommand() > 0;
}
public virtual async Task<int> ExecuteCommandWithOptLockAsync()
{
var updateData = UpdateObjs.FirstOrDefault();
if (updateData == null) return 0;
_ExecuteCommandWithOptLock(updateData);
return await this.ExecuteCommandAsync();
}
public virtual async Task<int> ExecuteCommandAsync()
{
string sql = _ExecuteCommand();
@@ -852,7 +868,28 @@ namespace SqlSugar
this.RemoveCacheFunc();
}
}
private void _ExecuteCommandWithOptLock(T updateData)
{
Check.ExceptionEasy(UpdateParameterIsNull == true, "Optimistic lock can only be an entity update method", "乐观锁只能是实体更新方式");
var verColumn = this.EntityInfo.Columns.FirstOrDefault(it => it.IsEnableUpdateVersionValidation);
Check.ExceptionEasy(verColumn == null, $" {this.EntityInfo.EntityName } need IsEnableUpdateVersionValidation=true ", $"实体{this.EntityInfo.EntityName}没有找到版本标识特性 IsEnableUpdateVersionValidation");
Check.ExceptionEasy(UpdateObjs.Length > 1, $"Optimistic lock can only handle a single update ", $"乐观锁只能处理单条更新");
Check.ExceptionEasy(!verColumn.UnderType.IsIn(UtilConstants.StringType, UtilConstants.LongType, UtilConstants.GuidType, UtilConstants.DateType), $"Optimistic locks can only be guid, long, and string types", $"乐观锁只能是Guid、Long和字符串类型");
var oldValue = verColumn.PropertyInfo.GetValue(updateData);
var newValue = UtilMethods.GetRandomByType(verColumn.UnderType);
verColumn.PropertyInfo.SetValue(updateData, newValue);
var data = this.UpdateBuilder.DbColumnInfoList.First(it =>
it.PropertyName.EqualCase(verColumn.PropertyName));
data.Value = newValue;
var pks = GetPrimaryKeys();
this.Where(verColumn.DbColumnName, "=", oldValue);
foreach (var p in pks)
{
var pkColumn = this.EntityInfo.Columns.FirstOrDefault(
it => it.DbColumnName.EqualCase(p) || it.PropertyName.EqualCase(p));
this.Where(pkColumn.DbColumnName, "=", pkColumn.PropertyInfo.GetValue(updateData));
}
}
private void Before(string sql)
{
if (this.IsEnableDiffLogEvent)

View File

@@ -12,6 +12,8 @@ namespace SqlSugar
UpdateBuilder UpdateBuilder { get; set; }
bool UpdateParameterIsNull { get; set; }
int ExecuteCommandWithOptLock();
Task<int> ExecuteCommandWithOptLockAsync();
int ExecuteCommand();
bool ExecuteCommandHasChange();
Task<int> ExecuteCommandAsync();

View File

@@ -133,6 +133,30 @@ namespace SqlSugar
};
}
internal static object GetRandomByType(Type underType)
{
if (underType == UtilConstants.GuidType)
{
return Guid.NewGuid();
}
else if (underType == UtilConstants.LongType)
{
return SnowFlakeSingle.Instance.NextId();
}
else if (underType == UtilConstants.StringType)
{
return Guid.NewGuid() + "";
}
else if (underType == UtilConstants.DateType)
{
return System.DateTime.Now;
}
else
{
return Guid.NewGuid() + "";
}
}
public static bool IsAsyncMethod(MethodBase method)
{
if (method == null)