SQLite'ta transaction'lar ve sanal tablolar
(misfra.me)- SQLite sanal tabloları da yazma ve transaction desteğine sahiptir; bunun için
xUpdate,xSync,xCommit,xRollbackgibi hook'lar uygulanır - SQLite varsayılan olarak rollback journal yöntemiyle atomikliği garanti eder; birden fazla DB dosyasıyla çalışırken tüm commit'i super-journal ile koordine eder
- Sanal tablolar da SQLite'ın transaction protokolüne dahildir;
xSyncbaşarısız olursa tüm transaction rollback edilir - Commit iki aşamaya ayrılır;
xSyncbaşarısız olabilen işler,xCommitise yalnızca basit temizlik işleri yapmalıdır xCommitvexRollbackher zaman çağrılabileceğinden, bunlar başarısız olmadan çalışabilen temizlik amaçlı fonksiyonlar olarak yazılmalıdır
SQLite'ın sanal tabloları ve transaction işleme süreci
Önceki yazıda Go diliyle SQLite'ta sanal tablo kaydetmenin ve sorgulamanın temel yöntemleri tanıtılmıştı. Bu yazı ise yazılabilir ve transaction destekli sanal tabloların nasıl uygulanacağını ele alıyor.
Sanal tablolar için yazma ve transaction desteği
-
SQLite'ın sanal tablo arayüzü salt okunur değildir
-
xUpdatehook'unu uygularsanız harici veri kaynaklarına da yazabilirsiniz -
Gerçek transaction tutarlılığı için şu transaction hook'ları gerekir:
xBegin: transaction başlangıcının bildirimixSync: diske güvenli commit için hazırlık (burada hata olursa tüm işlem rollback edilir)xCommit: son commit ve temizlikxRollback: transaction kesintiye uğrarsa rollback yürütme
-
Normal tablolarla veya başka sanal tablolarla birlikte değişiklik yapıldığında da SQLite, atomikliği garanti etmek için tüm hook'ları birlikte koordine eder
SQLite transaction'larının içeride nasıl çalıştığı
Rollback journal'lar
- SQLite varsayılan olarak sayfaları ezmeden önce yedek dosyaya (journal) yazar
- Bir sorun çıkarsa journal'dan geri yükleyerek atomikliği garanti eder
> Not: SQLite WAL modunu da destekler, ancak bu yazının kapsamı dışında bırakılmıştır
Super-journal'lar
-
Birden fazla veritabanı bağlı olduğunda, yalnızca her DB için ayrı journal tutmak senkronizasyon için yeterli değildir
-
Super-journal adlı daha üst düzey bir dosya ile birden fazla dosya arasındaki commit koordine edilir
-
Tek bir DB dosyası içindeki birden fazla sanal tabloyla çalışılıyorsa super-journal olmadan da senkronizasyon mümkündür
-
Durum ne olursa olsun SQLite, transaction akışı içinde
xSync,xCommit,xRollbackhook'larını otomatik olarak çağırır
Sanal tablolarla iki aşamalı commit
SQLite'ın commit süreci iki aşamadan oluşur:
1. aşama: xSync (dayanıklılık garantisi)
- Tüm B-Tree ve DB dosyalarının sayfaları veya journal'ları diske güvenli biçimde senkronize edilir
- Her sanal tablo için de
xSynchook'u çağrılır - Herhangi bir
xSyncbaşarısız olursa tüm transaction rollback edilir → atomiklik korunur
2. aşama: temizlik (xCommit)
-
Diske yazma tamamlanınca journal dosyaları silinir ve sanal tablo temizliği yapılır
-
Aşağıda
vdbeaux.cdosyasından bir kod parçası yer alıyordisable_simulated_io_errors(); sqlite3BeginBenignMalloc(); for(i=0; i<db->nDb; i++){ Btree *pBt = db->aDb[i].pBt; if( pBt ){ sqlite3BtreeCommitPhaseTwo(pBt, 1); } } sqlite3EndBenignMalloc(); enable_simulated_io_errors(); sqlite3VtabCommit(db); -
sqlite3VtabCommit()içinde gerçekte tümxCommitçağrıları başarısız olsa bile yok sayılır → bu, tamamen bir temizlik aşamasıdırint sqlite3VtabCommit(sqlite3 *db){ callFinaliser(db, offsetof(sqlite3_module,xCommit)); return SQLITE_OK; } -
Dayanıklılık
xSyncile zaten sağlandığı için,xCommitvexRollbackhata verse bile yok sayılır
Sanal tablo yazarları için dikkat edilmesi gerekenler
- Kalıcı etkisi olan işler mutlaka
xSynciçine konulmalıdır- Ağ I/O'su, dosya yazma gibi başarısız olabilecek işler burada ele alınmalıdır ki transaction güvenli şekilde durdurulabilsin
xSyncsonrasında daxRollbackçağrılabilir- Başka bir tablonun
xSync'i başarısız olursa tüm transaction rollback edilir
- Başka bir tablonun
xCommitvexRollback, hata vermeyen temizlik fonksiyonları olarak yazılmalıdır- idempotent olmalı; birden fazla çağrılsa da durum değişmemelidir
Sonuç
- SQLite'ın journaling mekanizması, temel tablolar ve sanal tablolar dahil tüm bileşenlerde atomik commit'i garanti eder
- Sanal tablo transaction hook'ları, SQLite'ın transaction akışına doğal biçimde entegre olur
- Sanal tablo geliştirenler, veri bütünlüğünü sağlamak için
xSyncüzerine odaklanmalı; temizlik işlerini isexCommitvexRollbackarasında ayırmalıdır
1 yorum
Hacker News yorumu