- 增加 ISelect.ForUpdate 排他更新锁(根据数据库类型的规则,见代码注释);

- 完善 SqlServer WithLock 功能,组合多种使用 | 枚举相联;
This commit is contained in:
28810
2019-12-14 11:43:17 +08:00
parent 655d19153b
commit 15c3ab7297
32 changed files with 470 additions and 170 deletions

View File

@ -26,6 +26,7 @@ namespace FreeSql.Internal.CommonProvider
protected List<SelectTableInfo> _tables = new List<SelectTableInfo>();
protected List<Func<Type, string, string>> _tableRules = new List<Func<Type, string, string>>();
protected Func<Type, string, string> _aliasRule;
protected string _tosqlAppendContent;
protected StringBuilder _join = new StringBuilder();
protected IFreeSql _orm;
protected CommonUtils _commonUtils;
@ -990,6 +991,36 @@ namespace FreeSql.Internal.CommonProvider
}
return this as TSelect;
}
public TSelect ForUpdate(bool noawait = false)
{
if (_transaction == null && _orm.Ado.TransactionCurrentThread == null)
throw new Exception("安全起见,请务必在事务开启之后,再使用 ForUpdate");
switch (_orm.Ado.DataType)
{
case DataType.MySql:
case DataType.OdbcMySql:
_tosqlAppendContent = " for update";
break;
case DataType.SqlServer:
case DataType.OdbcSqlServer:
_aliasRule = (_, old) => $"{old} With(UpdLock, RowLock{(noawait ? ", NoWait" : "")})";
break;
case DataType.PostgreSQL:
case DataType.OdbcPostgreSQL:
_tosqlAppendContent = $" for update{(noawait ? " nowait" : "")}";
break;
case DataType.Oracle:
case DataType.OdbcOracle:
_tosqlAppendContent = $" for update{(noawait ? " nowait" : "")}";
break;
case DataType.Sqlite:
break;
case DataType.OdbcDameng:
_tosqlAppendContent = $" for update{(noawait ? " nowait" : "")}";
break;
}
return this as TSelect;
}
#region common
protected TMember InternalAvg<TMember>(Expression exp) => this.ToList<TMember>($"avg({_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, exp, true, null)})").FirstOrDefault();

View File

@ -636,13 +636,18 @@ namespace FreeSql.Internal.CommonProvider
foreach (var item in list)
setListValue(item, null);
var subSelect = _orm.Select<TNavigate>().DisableGlobalFilter().WithConnection(_connection).WithTransaction(_transaction).TrackToList(_trackToList) as Select1Provider<TNavigate>;
var subSelect = _orm.Select<TNavigate>()
.DisableGlobalFilter()
.WithConnection(_connection)
.WithTransaction(_transaction)
.TrackToList(_trackToList) as Select1Provider<TNavigate>;
if (_tableRules?.Any() == true)
foreach (var tr in _tableRules) subSelect.AsTable(tr);
if (_whereCascadeExpression.Any())
subSelect._whereCascadeExpression.AddRange(_whereCascadeExpression.ToArray());
//subSelect._aliasRule = _aliasRule; //把 SqlServer 查询锁传递下去
then?.Invoke(subSelect);
var subSelectT1Alias = subSelect._tables[0].Alias;
var oldWhere = subSelect._where.ToString();