Foruma hoş geldin 👋, Ziyaretçi

Forum içeriğine ve tüm hizmetlerimize erişim sağlamak için foruma kayıt olmalı ya da giriş yapmalısınız. Foruma üye olmak tamamen ücretsizdir.

Kendi Oyun Sunucumu Yazarken Database Deadlock'ları Bana Hayat Dersi Verdi

devnix

Üye
Katılım
14 Mart 2026
Mesajlar
15
Kafayı yiyecektim dostlar. Kendi oyun sunucumu yazıyorum, her şey güzel gidiyor derken, aniden oyun dünyası donuyor. Oyuncular "abi hareket etmiyor" diye isyan ediyor. Meğerse sorun, PostgreSQL'in derinliklerinde bir deadlock sarmalındaymış. Debug için harcadığım o saatler, kod yazmaktan çok, sabır testiydi.

🔴 Loglarda Gördüğüm Kabus

Sunucu loglarını açtım ve şu cümleyle karşılaştım: `deadlock detected`. İçimden "tamam, buldum" dedim. Aşağıya indim, detaylarına baktım. İki query birbirini bekliyordu. Biri oyuncunun envanterini güncelliyor, diğeri aynı oyuncunun ticaret teklifini işliyordu. İkisi de aynı satırlara kilit vurmaya çalışıyor, biri diğerini bırakmıyordu. StackOverflow'da bile bu kadar net bir örnek bulamazsınız.

SQL:
-- Process 123: UPDATE inventory SET item_id = 5 WHERE player_id = 42;
-- Process 456: UPDATE trade_offers SET status = 'accepted' WHERE player_id = 42;

🔵 Debug Süreci ve İsyanım

İlk başta, "transaction isolation level" ile oynayayım dedim. Belki READ COMMITTED yetmez, REPEATABLE READ denerim diye düşündüm. Şaka gibi ama, durum daha da kötüleşti. Sonra fark ettim ki, asıl mesele transaction'ları sıraya sokmak değil, kilit alma sırasını (lock order) tutarlı hale getirmekmiş.

Koduma döndüm, bütün update ve delete işlemlerini taradım. "Acaba hangi tabloya önce, hangisine sonra lock atıyorum?" diye. Meğerse, EnvanterService sınıfımda tablolara bir sırada, TradeService'te ise tam tersi bir sırada erişiyormuşum. İnanılmaz bir detay ve saatlerimi yedi.

✅ Çözüm ve Alınan Ders

Çözüm aslında basitti: Global bir lock sırası belirlemek. Projede bir doküman açtım, başına "DEADLOCK KORUMA PROTOKOLÜ" yazdım. İçine "Tüm transaction'larda tablolara şu sırada erişilecek: 1. players, 2. inventory, 3. trade_offers..." diye bir kural koydum. Ve tabii ki, tüm transaction'ları mümkün olduğunca kısa tutmak.

Aldığım hayat dersi şu: Kodu yazarken "çalışıyor" olması yetmez. Özellikle multi-thread ve database işlerinde, kaynaklara erişim sırası, çalışmasından daha kritik olabilir. Bir daha asla "lock order"ı hafife almam.

Siz de böyle görünmez bir deadlock tuzağına düşüp, saatlerinizi debug'a harcadınız mı? Bu işin otomatik tespiti için pg_stat_activity dışında kullandığınız pratik bir yöntem var mı?
 

Tema özelleştirme sistemi

Bu menüden forum temasının bazı alanlarını kendinize özel olarak düzenleye bilirsiniz.

Zevkine göre renk kombinasyonunu belirle

Tam ekran yada dar ekran

Temanızın gövde büyüklüğünü sevkiniz, ihtiyacınıza göre dar yada geniş olarak kulana bilirsiniz.

Geri