fix: identity 登录并发改为 xmin
All checks were successful
Build and Deploy TenantApi / build-and-deploy (push) Successful in 8s

移除 identity_users 对 RowVersion 列的依赖,改用 PostgreSQL xmin 作为并发令牌,修复线上登录因缺失 RowVersion 列导致的 500 错误。
This commit is contained in:
2026-02-06 12:11:52 +08:00
parent f10319d96b
commit ec5293d892
4 changed files with 8 additions and 10 deletions

View File

@@ -50,9 +50,7 @@ public sealed record UpdateIdentityUserCommand : IRequest<UserDetailDto?>
public string[]? RoleIds { get; init; }
/// <summary>
/// 并发控制版本。
/// 并发控制版本(兼容字段,当前由数据库 xmin 托管)
/// </summary>
[Required]
[MinLength(1)]
public byte[] RowVersion { get; init; } = Array.Empty<byte>();
public byte[]? RowVersion { get; init; }
}

View File

@@ -87,7 +87,6 @@ public sealed class UpdateIdentityUserCommandHandler(
user.Phone = phone;
user.Email = email;
user.Avatar = string.IsNullOrWhiteSpace(request.Avatar) ? null : request.Avatar.Trim();
user.RowVersion = request.RowVersion;
// 6. 构建操作日志消息
var operatorName = string.IsNullOrWhiteSpace(operatorProfile.DisplayName)

View File

@@ -16,7 +16,6 @@ public sealed class UpdateIdentityUserCommandValidator : AbstractValidator<Updat
RuleFor(x => x.UserId).GreaterThan(0);
RuleFor(x => x.DisplayName).NotEmpty().MaximumLength(64);
RuleFor(x => x.Avatar).MaximumLength(512);
RuleFor(x => x.RowVersion).NotEmpty();
RuleFor(x => x.TenantId).GreaterThan(0).When(x => x.TenantId.HasValue);
RuleForEach(x => x.RoleIds)
.Must(value => long.TryParse(value, out _))

View File

@@ -104,10 +104,12 @@ public sealed class IdentityDbContext(
builder.Property(x => x.LastLoginAt);
builder.Property(x => x.MustChangePassword).IsRequired();
builder.Property(x => x.Avatar).HasColumnType("text");
builder.Property(x => x.RowVersion)
.IsRowVersion()
.IsConcurrencyToken()
.HasColumnType("bytea");
builder.Ignore(x => x.RowVersion);
builder.Property<uint>("xmin")
.HasColumnName("xmin")
.HasColumnType("xid")
.ValueGeneratedOnAddOrUpdate()
.IsConcurrencyToken();
builder.Property(x => x.TenantId).IsRequired();
ConfigureAuditableEntity(builder);
ConfigureSoftDeleteEntity(builder);