跳转到主要内容

efcore

dotnet -ef 乱码修复

 

[Console]::OutputEncoding = [System.Text.Encoding]::UTF8

防止并发修改

1 乐观锁(推荐)
在实体中添加版本号或时间戳字段,每次更新时检查版本是否变化
public class Entity
{
public int Id { get; set; }
public string Name { get; set; }
public int Version { get; set; } // 版本号
}
// EF Core 配置
modelBuilder.Entity<Entity>().Property(e => e.Version).IsConcurrencyToken();
// 更新时自动检查
var entity = await context.Entities.FindAsync(id);
entity.Name = "new name";
await context.SaveChangesAsync(); // 如果版本冲突会抛出 DbUpdateConcurrencyException
捕获异常后处理:
try
{
await context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
// 重新加载最新数据,合并变更或提示用户
}
2 悲观锁
使用数据库行锁,适合高冲突场景
// SQL Server
SELECT * FROM Entities WITH (UPDLOCK, ROWLOCK) WHERE Id = @id
// MySQL
SELECT * FROM Entities WHERE Id = @id FOR UPDATE
在 EF Core 中执行原始 SQL 锁定,然后在事务中更新
3 分布式锁
适合跨服务或多实例场景,使用 Redis 等
var lockKey = $"lock:entity:{id}";
var acquired = await redis.StringSetAsync(lockKey, "1", TimeSpan.FromSeconds(10), When.NotExists);
if (!acquired)
{
throw new Exception("资源正在被其他请求修改");
}
try
{
// 执行更新操作
}
finally
{
await redis.KeyDeleteAsync(lockKey);
}
4 业务层面控制
接口幂等性设计,前端防重复提交,后端验证状态
建议优先使用乐观锁,性能最好且实现简单。高冲突场景再考虑悲观锁或分布式锁。