Welcome to CodeYourCraft, where we turn coding mysteries into clear-cut solutions! Today, we're diving into the fascinating world of Optimistic vs Pessimistic Locking. This lesson will be practical, engaging, and tailored to both beginners and intermediates. Let's get started!
Concurrency control is a technique used in databases to manage and resolve conflicts when multiple transactions try to access and modify data simultaneously.
What is the purpose of Concurrency Control in databases?
Optimistic locking is a concurrency control technique that assumes conflicts will be rare. It relies on a validation check before committing a transaction.
Optimistic locking works by allowing multiple transactions to read and modify the data simultaneously. However, before committing a transaction, it checks if the data has been modified by another transaction since the original read. If a conflict is detected, the transaction is rolled back, and the user is prompted to retry.
Optimistic locking is ideal for read-heavy applications where conflicts are infrequent. It's also a good choice when you have a high degree of concurrency but don't want to lock resources for extended periods.
class Item:
def __init__(self, name, version=0):
self.name = name
self.version = version
def lock(self):
self.version += 1
def unlock(self):
self.version -= 1
def try_to_update(self, new_name):
if self.version != other_version:
print("Error: Data has been modified by another transaction.")
return False
self.name = new_name
self.version += 1
return True
item = Item("Book")
other_version = item.version
item.try_to_update("New Book") # If another transaction modifies the item, an error will occur
Pessimistic locking, on the other hand, assumes conflicts will be frequent. It locks resources for the duration of a transaction to prevent conflicts.
Pessimistic locking locks a resource as soon as a transaction reads it, preventing other transactions from modifying the data until the first transaction is committed or rolled back.
Pessimistic locking is ideal for write-heavy applications where conflicts are frequent. It's also a good choice when you want to ensure consistent data, even at the expense of performance.
class Database:
def __init__(self):
self.items = {"Book": 1}
self.locks = {}
def lock(self, item):
self.locks[item] = True
def unlock(self, item):
del self.locks[item]
def try_to_update(self, item, new_value):
if item in self.locks:
print("Error: Resource is locked by another transaction.")
return False
self.items[item] = new_value
self.lock(item)
return True
db = Database()
db.try_to_update("Book", 2) # Another transaction can't modify "Book" until this transaction is committed or rolled back
Optimistic Locking
Pessimistic Locking
The choice between optimistic and pessimistic locking depends on the application's characteristics, such as the ratio of reads to writes and the level of concurrency.
That's all for today's lesson! We hope you enjoyed learning about Optimistic vs Pessimistic Locking. Stay tuned for more engaging and informative lessons on CodeYourCraft! 🚀