آپتیمیستیک لاکینگ (Optimistic Locking) یا قفلگذاری خوشبینانه، تغییر داده را در لحظه نوشتن با نسخهای که قبلا خوانده شده مقایسه میکند. اگر رکورد در این فاصله تغییر کرده باشد، UPDATE انجام نمیشود و برنامه باید تعارض را مدیریت یا عملیات را تکرار کند. برخلاف پسیمیستیک لاکینگ، در فاصله خواندن تا نوشتن قفل بلندمدت ردیف نگه نمیدارد.
نمونه SQL، جلوگیری از Lost Update
-- Read stock and version first.
UPDATE products
SET stock = 7, version = version + 1
WHERE id = 42 AND version = 5;
-- affected rows = 0 means a concurrent update won.
نمونه Laravel
$updated = DB::table('products')
->where('id', $id)->where('version', $expectedVersion)
->update(['stock' => $newStock, 'version' => $expectedVersion + 1]);
if ($updated === 0) {
throw new RuntimeException('Concurrent change, reload data');
}
نمونه Python و SQLAlchemy
from sqlalchemy import update
stmt = (update(Product)
.where(Product.id == product_id, Product.version == expected)
.values(stock=new_stock, version=expected + 1))
result = session.execute(stmt)
if result.rowcount != 1:
raise RuntimeError("Concurrent modification")
session.commit()
نمونه C# و EF Core
// Version should be configured as a concurrency token.
product.Stock = newStock;
try { await db.SaveChangesAsync(); }
catch (DbUpdateConcurrencyException) {
// Reload and resolve the conflict before retrying.
}
این روش برای فرمهای ویرایش طولانی و تعارضهای نسبتا نادر مناسب است. وقتی تداخل مکرر است یا هزینه تکرار بالا میرود، مقایسه با روش بدبینانه ارزش دارد.
برای تشخیص شرایط انتخاب، مقاله کامل باورژن درباره Optimistic و Pessimistic Locking را مطالعه کنید.