使用IsConcurrencyToken()设置并发token
builder.Property(h => h.Owner).IsConcurrencyToken();
使用SQL语句类似以下
update house set owner = @p0
where id = 1 and owner = @p1
-- 通过引用旧的owner值来更新,如果owner值已改变,则更新失败,发出DbUpdateConcurrencyException。
捕获DbUpdateConcurrencyException,获取新Token的值。
catch (DbUpdateConcurrencyException ex)
{
var entry = ex.Entries.First();
var dbValues = await entry.GetDatabaseValuesAsync();
string newOwner = dbValues.GetValue<string>(nameOf(House.Owner));
Console.WriteLine($"concurrency error, {newOwner} is owner now");
}
使用RowVersion控制并发
- 增加RowVer属性
public byte[] RowVer { get; set; }
- 设置RowVersion
builder.Property(c => c.RowVer).IsRowVersion();
原理和上面一样,只是改为判断RowVersion。
3. 测试代码和上例一样,也通过捕获DbUpdateConcurrencyException,取得owner的新值。
注意
方案1,会有ABA的问题,即值发生过改变,但又改回来了,这样就需要考虑RowVersion是不是更合适了。