2011-03-25 18 views
10

Bir veritabanı tablosunda bir alanı Hazırda Bekletme özelliğini kullanarak 1 arttırmak istiyorum.Hazırda bekletme: Bir tamsayı alanı artırma

Bunu yalnızca bir nesneyi yükleyerek, değeri artırarak ve nesneyi güncelleyerek yapabilirim, ancak başka bir iş parçacığı gelirse ve yük ile güncelleştirme arasındaki alanı güncelleştirirse değer bozulur. Bunun yerine ben veritabanı üzerinde doğrudan bir güncelleme çağrıda

:

Ancak
Query updateHits = createQuery(
    "UPDATE Job SET hitCount = hitCount + 1 WHERE id = :jobId"); 
updateHits.setInteger("jobId", job.getId()); 
updateHits.executeUpdate(); 

benim anlayış bu veritabanındaki iyimser kilitleme atlar ve şu anda SQL server çözümsüzlüklerle ile bir sorunu yaşıyorum ve inanıyorum ki Bu suçlu.

Güncelleştirmeyi doğrudan aramadan ve veri bütünlüğünü koruyarak bir alanı artırmanın bir yolu var mı?

+0

Kilitlerinizin nasıl oluşturulduğunu görmek isteyip istemediğinizi kontrol etmek isteyebilirsiniz. Güncelleme için bir masa kilidi alıyorsanız, bir sorun var. Eğer bir satır kilidi alıyorsanız, nasıl bir çıkmaza neden olacağını görmüyorum. – BlackICE

+0

Aslında, bu güncellemenin işlem içerisindeki son ifadesi olduğundan emin olmak için kilitlenme sorununu çözmeyi başardım. Ancak hala daha iyi çözümler bilmemle ilgileniyorum. – 3urdoch

+1

"increment-by-query" çözümünüz, özellikle multi-thread ve uzun süreli işlemlerde çalışıyorsanız, kötümser kilitlerle uğraşmaktan on kat daha iyidir. – kommradHomer

cevap

3

başka parçacığı ortaya çıkınca ve daha sonra değer haline gelecektir yük ve güncelleme arasına alanını günceller eğer ben sadece, bir nesnesi yükleme değer artırma ve ancak nesneyi güncelleyerek yapabilirsiniz bozuk.

ikinci iplik de hazırda kullanıyorsa ve hazırda sürüm (@version) ilk taahhüt ve nesne nesne üzerinde yeni sürümü kuracak değiştirir tek iplik kullanıyorsanız.

İkinci iş parçacığı iletimi geldiğinde, hazırda bekletme iyimser kilit başarısızlığını denetler ve bir istisna atar - Yanılmıyorsam, StaleObjectException. Eşzamanlı kodunuzun etrafındaki bir yakalama bloğu, nesneyi tekrar yükleme şansına sahip olacak ve eğer mantıklı olursa güncellemenizi deneyebileceksiniz. JPA kullanıyorsanız bir OptimisticLockException atılır.

Hibernate Optimistic Concurrency Control Section adresinde fazla bilgi bulunmaktadır.

Şerefe!

İlgili konular