24 Ekim 2018 Çarşamba

Optimistic Locking

Giriş
Optmistic Locking kullanıyorsak tabloda sürüm numarasını gösteren bir sütun bulunur. Okuma yapıp bilgiyi ekranda gösterirken bu bilgi başkası tarafından güncellenebilir. Dolayısıyla Non-Repetable Read ile aynı kapıya çıkar.

Neden Optimistic Lock Var ?
Amaç contention'ı (rekabet?) azaltmak. Açıklaması şöyle. Buna Multi-Version Concurrency Control (MVCC) deniliyor.
By allowing multiple versions of the same record, there is going to be less contention on reading/writing records since Readers will not block writers and Writers will not block Readers as well.
Optimistic Lock MVCC ile aynı. Açıklaması şöyle
Like MVCC, optimistic locking defines a versioning concurrency control model that works without acquiring additional database write locks.
Bize Maliyeti Nedir
Optimistic Lock ile rekabet azalıyor ancak yazma işlemi sonunda exception fırlatılabiliyor. Yani aslında yazma gerçekleşmiyor. İşlemin tekrarlanması zorunluluğu bir maliyet kabul edilebilir.

Ayrıca sürüm numarasını öğrenmek için önce bir okuma (read) işlemi yapmak gerekiyor. Açıklaması şöyle. Bu da bir başka maliyet kabul edilebilir.
In order for optimistic locking to work correctly, any transaction that decides to update a given record must read that record first. This is because the transaction must know what is the current VERSION field value in order to use it later in the update statement.

Yazma İşleminin Gerçekleşmemesinin Sebebi Nedir
Açıklaması şöyle. Yani Hibernate Optimistic Lock kullanıyorsa update cümlesine version sütununu da otomatik olarak ilave eder. Böylece satır bizden habersiz olarak güncellenirse yazma işlemi etkisiz işlem haline gelir.
Every UPDATE takes the load-time version into the WHERE clause, assuming no one has changed this row since it was retrieved from the database. If some other transaction manages to commit a newer entity version, the UPDATE WHERE clause will no longer match any row and so the lost update is prevented.

Hibernate uses the PreparedStatement#executeUpdate result to check the number of updated rows. If no row was matched, it then throws a StaleObjectStateException (when using Hibernate API) or an OptimisticLockException (when using JPA).
Yazma İşlemi Başarısız İse Ne Yapmak Lazım
Kısaca yazma işlemi tekrarlamak gerekiyor.

Açıklaması şöyle. Yani eğer satır bir başkası tarafından güncellenmişse ekranda hata mesajı gösterilebilir veya REST çağrısı ise hata kodu dönülür.
The ETag mechanism specifies only the communication protocol for optimistic locking. It's the responsibility of the application service to implement the mechanism to detect concurrent updates to enforce the optimistic lock.

In a typical application that uses a database, you'd usually do this by opening a transaction when processing a PUT request. You'd normally read the existing state of the database inside that transaction (to gain a read lock), check your Etag validity, and overwrite the data (in a way that'll cause a write conflict when there's any incompatible concurrent transaction), then commit. If you setup the transaction correctly, then one of the commits should fail because they'll both be trying to update the same data concurrently. You'll then be able to use this transaction failure to either return 412 or retry the request, if it makes sense for the application.
Hibernate ile optimistic locking kullanılınca ekranda hatayı göstermek için iyi bir örneği burada buldum.

Optimistic Lock Nasıl Etkinleştirilir
JPA Entity sınıfında @Version anotasyonu kullanan bir alan olması gerekir. Açıklaması şöyle.
Implementing the optimistic locking in JPA is quite simple. You just have to configure your entities with a field annotated with @Version. The JPA provider will take care of issuing update statements in the form we have seen previously (incrementing and checking the version field in each update of a versioned entity) and will also automatically check for the updated row count in order to detect concurrent updates.

If a conflict is detected the JPA provider will throw a javax.persistence.OptimisticLockException.


Hiç yorum yok:

Yorum Gönder