💡SQL Server
یک قابلیت مشابه با sp_getapplock دارد.
بررسی کتابخانه DistributedLock 🔍
در حالی که رویکرد DIY کار میکند، اپلیکیشنهای پروداکشن به ویژگیهای پیچیدهتری نیاز دارند. کتابخانه DistributedLock موارد استثنایی (edge cases) را مدیریت کرده و چندین گزینه بکاند (Postgres, Redis, SqlServer و غیره) را فراهم میکند. شما میدانید که من طرفدار اختراع مجدد چرخ نیستم، بنابراین این یک انتخاب عالی است.
پکیج را نصب کنید: 📦
Install-Package DistributedLock
من از رویکردی با IDistributedLockProvider استفاده خواهم کرد که به خوبی با DI کار میکند. شما میتوانید یک قفل را بدون اینکه چیزی در مورد زیرساخت زیرین بدانید، به دست آورید. تمام کاری که باید انجام دهید این است که یک پیادهسازی از lock provider را در کانتینر DI خود ثبت کنید.
برای مثال، با استفاده از Postgres: 🔧
// Register the distributed lock provider
builder.Services.AddSingleton<IDistributedLockProvider>(
(_) =>
{
return new PostgresDistributedSynchronizationProvider(
builder.Configuration.GetConnectionString("distributed-locking")!);
});
یا اگر میخواهید از Redis با الگوریتم Redlock استفاده کنید:
// Requires StackExchange.Redis
builder.Services.AddSingleton<IConnectionMultiplexer>(
(_) =>
{
return ConnectionMultiplexer.Connect(
builder.Configuration.GetConnectionString("redis")!);
});
// Register the distributed lock provider
builder.Services.AddSingleton<IDistributedLockProvider>(
(sp) =>
{
var connectionMultiplexer = sp.GetRequiredService<IConnectionMultiplexer>();
return new RedisDistributedSynchronizationProvider(connectionMultiplexer.GetDatabase());
});
نحوه استفاده سرراست است: 👨💻
// شما همچنین میتوانید یک تایماوت پاس دهید، که در آن provider به تلاش برای به دست آوردن قفل
// تا رسیدن به تایماوت ادامه خواهد داد.
IDistributedSynchronizationHandle? distributedLock = distributedLockProvider
.TryAcquireLock("nightly-report");
// اگر قفل را به دست نیاوردیم، آبجکت null خواهد بود
if (distributedLock is null)
{
return Results.Conflict();
}
// مهم است که قفل را در یک دستور using بپیچید تا اطمینان حاصل شود که به درستی آزاد میشود
using (distributedLock)
{
await DoWork();
}
این کتابخانه تمام بخشهای دشوار را مدیریت میکند 👍: تایماوتها، تلاشهای مجدد، و تضمین اینکه قفلها حتی در سناریوهای شکست نیز آزاد میشوند.
این همچنین از بسیاری از بکاندها (SQL Server, Azure, ZooKeeper و غیره) پشتیبانی میکند، که آن را به یک انتخاب محکم برای بارهای کاری پروداکشن تبدیل میکند.
جمعبندی 📝
قفلگذاری توزیعشده چیزی نیست که هر روز به آن نیاز داشته باشید. اما وقتی به آن نیاز پیدا میکنید، شما را از باگهای ظریف و دردناکی که فقط تحت بار یا در پروداکشن ظاهر میشوند، نجات میدهد.
🔹 ساده شروع کنید: اگر از قبل از Postgres استفاده میکنید، advisory locks یک ابزار قدرتمند است.
🔹 برای یک تجربه توسعهدهنده تمیزتر، به سراغ کتابخانه DistributedLock بروید.
🔹 بکاندی را انتخاب کنید که متناسب با زیرساخت شما باشد (Postgres, Redis, SQL Server و غیره).
قفل مناسب در زمان مناسب تضمین میکند که سیستم شما سازگار، قابل اعتماد و انعطافپذیر باقی بماند، حتی در چندین فرآیند و سرور.(منبع)