Abp Core,处理数据库数据级乐观并发,可以使用ConcurrencyCheck特性
步骤如下:
1.在需要防止并发的实体层表结构中,增加一个时间类型字段,加上ConcurrencyCheck特性
public class Reward: Entity
{
/// <summary></summary>
[Description("")]
public string Name { get { return _Name; } set { _Name = value ?? ""; } }
// Name
private string _Name = "";
[ConcurrencyCheck]
public DateTime TimestampV { get; set; }
}
2.更新数据库表结构
3.设置时间字段的默认值
如果是mysql数据库,则把字段类型从datetime改为timestamp,并设置字段默认值为CURRENT_TIMESTAMP,勾选On update Current_Timestamp
如果是sqlserver数据库,则设置字段默认值为getdate(),并设置触发器,修改的时候也更新字段值为getdate()
4.业务逻辑中,拦截DbConcurrencyException,获取并发错误
try
{
await _rewardAppService.Update(reward);
await UnitOfWorkManager.Current.SaveChangesAsync();
}
catch (Abp.Domain.Uow.AbpDbConcurrencyException ex)
{
throw new UserFriendlyException("出现并发错误,另一个人也在同时修改该条记录,并且更早提交修改,请重试!");
}
catch (Exception ex)
{
throw ex;
}
5.如果不用AsyncCrudAppService默认的Update方法,而使用自定义方法更新,查询Entity的时候,必须使用Repository.Get或者Repository.GetAsync,如果使用Repository.GetAll().FirstOrDefault()查询到Entity后进行更新,则无法触发乐观并发锁
public async Task<RewardDto> UpdateByMySelf(RewardDto input)
{
var entity = await Repository.GetAsync(input.Id);
MapToEntity(input, entity);
await CurrentUnitOfWork.SaveChangesAsync();
return MapToEntityDto(entity);
}