using MAX.Core.DependencyInjection; using MAX.Framework.Commons; using Microsoft.Extensions.Configuration; using MySql.Data.MySqlClient; using System.Security.Cryptography; using System.Text; namespace Store.Modules.CloudProduct.Services; /// 跨实例串行化违规上报和商品索引写入,防止下架后被旧批次写回。 public class GoodsIndexLock(IConfiguration configuration) : ISingletonDependency { public async Task AcquireAsync() { // 禁用连接池:即使释放锁失败,关闭物理连接也会释放会话锁。 var settings = new MySqlConnectionStringBuilder(configuration["CloudProductConnection"]) { Pooling = false }; var connection = new MySqlConnection(settings.ConnectionString); var name = "goods-index:" + Convert.ToHexString(SHA256.HashData( Encoding.UTF8.GetBytes(settings.Database)))[..40]; try { await connection.OpenAsync(); using var command = connection.CreateCommand(); command.CommandText = "SELECT GET_LOCK(@name, 30)"; command.CommandTimeout = 35; command.Parameters.AddWithValue("@name", name); var result = await command.ExecuteScalarAsync(); if (result == null || result == DBNull.Value || Convert.ToInt32(result) != 1) throw new AppException("商品索引正在处理,请稍后重试"); return connection; } catch { await connection.DisposeAsync(); throw; } } }