| | |
| | | using Microsoft.Extensions.Logging; |
| | | using Newtonsoft.Json; |
| | | using WIDESEAWCS_Common; |
| | | using WIDESEAWCS_Core.LogHelper; |
| | | using WIDESEAWCS_ITaskInfoRepository; |
| | | using WIDESEAWCS_Model.Models; |
| | |
| | | /// </summary> |
| | | /// <remarks> |
| | | /// 核心功能是通过 IRobotStateRepository 管理数据库中的机械手状态。 |
| | | /// 提供乐观并发控制,通过 RowVersion 防止并发更新时的数据覆盖问题。 |
| | | /// 提供乐观并发控制,通过 Version 字段防止并发更新时的数据覆盖问题。 |
| | | /// </remarks> |
| | | public class RobotStateManager |
| | | { |
| | |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 安全更新 RobotSocketState 缓存,防止并发覆盖 |
| | | /// 安全更新 RobotSocketState,防止并发覆盖 |
| | | /// </summary> |
| | | /// <remarks> |
| | | /// 使用乐观并发模式:先读取当前 RowVersion,执行更新时检查版本是否一致。 |
| | | /// 如果 RowVersion 不匹配(说明有其他线程已更新),则更新失败返回 false。 |
| | | /// 使用乐观并发模式:先读取当前 Version,执行更新时检查版本是否一致。 |
| | | /// 如果 Version 不匹配(说明有其他线程已更新),则更新失败返回 false。 |
| | | /// </remarks> |
| | | /// <param name="ipAddress">设备 IP 地址</param> |
| | | /// <param name="updateAction">更新状态的委托函数,传入当前状态副本,返回修改后的新状态</param> |
| | |
| | | return false; |
| | | } |
| | | |
| | | // 记录当前存储的 RowVersion,作为更新时的期望版本 |
| | | var expectedRowVersion = currentEntity.RowVersion; |
| | | // 记录当前存储的 Version,作为更新时的期望版本 |
| | | var expectedVersion = currentEntity.Version; |
| | | |
| | | // 创建状态的深拷贝副本(使用 JSON 序列化实现) |
| | | var stateCopy = CloneState(_repository.ToSocketState(currentEntity)); |
| | |
| | | |
| | | // 将新状态转换为数据库实体 |
| | | var newEntity = _repository.ToEntity(newState); |
| | | newEntity.RowVersion = Array.Empty<byte>(); // SqlSugar 会自动管理 |
| | | newEntity.Id = currentEntity.Id; |
| | | newEntity.Version = expectedVersion + 1; // 版本自增 |
| | | |
| | | // 调用仓储的安全更新方法,传入期望 RowVersion |
| | | // 如果 RowVersion 不一致(已被其他线程更新),则更新失败 |
| | | return _repository.TryUpdate(ipAddress, newEntity, expectedRowVersion); |
| | | // 调用仓储的安全更新方法,传入期望 Version |
| | | // 如果 Version 不一致(已被其他线程更新),则更新失败 |
| | | return _repository.TryUpdate(ipAddress, newEntity, expectedVersion); |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | // 如果当前不存在该设备的状态,创建新记录 |
| | | if (currentEntity == null) |
| | | { |
| | | var entity = _repository.ToEntity(newState); |
| | | entity.CreateTime = DateTime.Now; |
| | | entity.UpdateTime = DateTime.Now; |
| | | _repository.GetOrCreate(newState.IPAddress, newState.RobotCrane ?? new RobotCraneDevice()); |
| | | _logger.LogDebug("TryUpdateStateSafely:创建新状态,IP: {IpAddress}", ipAddress); |
| | | QuartzLogger.Debug($"创建新状态,IP: {ipAddress}", ipAddress); |
| | | return true; |
| | | } |
| | | |
| | | // 当前存在状态,记录期望 RowVersion 用于乐观锁检查 |
| | | var expectedRowVersion = currentEntity.RowVersion; |
| | | // 当前存在状态,记录期望 Version 用于乐观锁检查 |
| | | var expectedVersion = currentEntity.Version; |
| | | |
| | | // 将新状态转换为数据库实体 |
| | | var newEntity = _repository.ToEntity(newState); |
| | | newEntity.Id = currentEntity.Id; |
| | | newEntity.RowVersion = Array.Empty<byte>(); |
| | | newEntity.Version = expectedVersion + 1; // 版本自增 |
| | | |
| | | // 尝试安全更新,如果版本冲突则返回 false |
| | | bool success = _repository.TryUpdate(ipAddress, newEntity, expectedRowVersion); |
| | | bool success = _repository.TryUpdate(ipAddress, newEntity, expectedVersion); |
| | | |
| | | if (!success) |
| | | { |
| | | _logger.LogWarning("TryUpdateStateSafely:版本冲突,更新失败,IP: {IpAddress},期望版本字节长度: {ExpectedLength}", ipAddress, expectedRowVersion.Length); |
| | | _logger.LogWarning("TryUpdateStateSafely:版本冲突,更新失败,IP: {IpAddress},期望版本: {ExpectedVersion}", ipAddress, expectedVersion); |
| | | QuartzLogger.Warn($"版本冲突,更新失败,IP: {ipAddress}", ipAddress); |
| | | } |
| | | |