Hayır. CouchDB "iyimser eşzamanlılık" modeli kullanır. En basit ifadeyle, bu sadece güncellemenizle birlikte bir belge sürümü gönderdiğiniz anlamına gelir ve CouchDB, geçerli belge sürümü gönderdiğinizle eşleşmezse değişikliği reddeder.
Gerçekten aldatıcı derecede basit. CouchDB için birçok normal işlem tabanlı senaryoyu yeniden çerçeveleyebilirsiniz. Yine de, CouchDB'yi öğrenirken RDBMS alan bilginizi atmanız gerekir. Couch'ı SQL tabanlı bir dünyaya dönüştürmeye çalışmak yerine problemlere daha yüksek bir seviyeden yaklaşmak yararlıdır.
Envanter takibi
Anlattığınız sorun öncelikle bir envanter sorunudur. Bir öğeyi açıklayan bir belgeniz varsa ve "mevcut miktar" için bir alan içeriyorsa, eşzamanlılık sorunlarını şu şekilde halledebilirsiniz:
- Belgeyi alın,
_rev
CouchDB'nin gönderdiği özelliği not alın
- Sıfırdan büyükse miktar alanını azaltın
_rev
Özelliği kullanarak güncellenmiş belgeyi geri gönderin
- Eğer
_rev
şu anda depolanmış numarayı maçları yapılabilir!
- Bir çakışma varsa (
_rev
eşleşmediğinde), en yeni belge sürümünü alın
Bu durumda, üzerinde düşünülmesi gereken iki olası arıza senaryosu vardır. En son belge sürümünün miktarı 0 ise, bunu tıpkı bir RDBMS'de yaptığınız gibi ele alın ve kullanıcıyı satın almak istediklerini gerçekten satın alamayacakları konusunda uyarırsınız. En son belge sürümünün miktarı 0'dan büyükse, işlemi güncellenmiş verilerle tekrarlayın ve en baştan başlayın. Bu, sizi bir RDBMS'den biraz daha fazla iş yapmaya zorlar ve sık sık çakışan güncellemeler varsa biraz can sıkıcı olabilir.
Şimdi, az önce verdiğim cevap, bir RDBMS'de yaptığınız gibi CouchDB'de de şeyler yapacağınızı öngörüyor. Bu soruna biraz farklı yaklaşabilirim:
Tüm tanımlayıcı verileri (ad, resim, açıklama, fiyat, vb.) İçeren bir "ana ürün" belgesiyle başlayacağım. Daha sonra, her bir örnek için product_key
ve alanları olan bir "envanter bileti" belgesi eklerdim claimed_by
. Eğer çekiç bir model satan ve satış için 20 tanesi var ediyorsanız gibi tuşlarıyla da belgeler olabilir hammer-1
, hammer-2
mevcut her çekiç temsil etmek, vb.
Daha sonra, bana bir "toplam" görmeme izin veren azaltma işleviyle birlikte mevcut çekiçlerin bir listesini veren bir görünüm oluşturdum. Bunlar tamamen yanlıştır, ancak size çalışma görünümünün nasıl görüneceği konusunda bir fikir vermelidir.
Harita
function(doc)
{
if (doc.type == 'inventory_ticket' && doc.claimed_by == null ) {
emit(doc.product_key, { 'inventory_ticket' :doc.id, '_rev' : doc._rev });
}
}
Bu bana ürün anahtarına göre mevcut "biletlerin" bir listesini veriyor. Biri bir çekiç satın almak istediğinde bunlardan bir grup alabilirim, ardından başarılı bir şekilde bir tane talep edene kadar güncellemeleri göndererek ( id
ve kullanarak _rev
) yineleyebilirim (önceden talep edilen biletler bir güncelleme hatasıyla sonuçlanacaktır).
Azalt
function (keys, values, combine) {
return values.length;
}
Bu azaltma işlevi, yalnızca sahip olunmayan inventory_ticket
öğelerin toplam sayısını döndürür , böylece satın alınabilecek kaç "çekiç" olduğunu anlayabilirsiniz.
Uyarılar
Bu çözüm, sunduğunuz belirli sorun için kabaca 3,5 dakikalık toplam düşünmeyi temsil eder. Bunu yapmanın daha iyi yolları olabilir! Bununla birlikte, çakışan güncellemeleri önemli ölçüde azaltır ve yeni bir güncellemeyle bir çatışmaya yanıt verme ihtiyacını azaltır. Bu model altında, birincil ürün girişindeki verileri değiştirmeye çalışan birden fazla kullanıcınız olmayacak. En kötüsü, tek bir bilet talep etmeye çalışan birden fazla kullanıcı olacak ve bunlardan birkaçını sizin görüşünüzden yakaladıysanız, bir sonraki bilete geçip tekrar deneyin.
Referans: https://wiki.apache.org/couchdb/Frequently_asked_questions#How_do_I_use_transactions_with_CouchDB.3F