2011-03-20 20 views
10

C# içindeki SQLite veritabanına erişmek için System.Data.Sqlite kullanıyorum. Tablodaki satırları okuması gereken bir sorgum var. Satırlar arasında geçiş yaparken ve okuyucu açıkken, bazı SQL güncellemeleri gerçekleştirilmelidir. Bir "veritabanı kilitli" istisna koşuyorum.SQLite sorgusunu veritabanını kilitlemeden bir veri okuyucu ile nasıl gerçekleştirirsiniz?

SQLite documentation devletler:

bir süreç, bir veritabanı dosyasından okumak istediği

, bu adımları sırayla takip:

  1. Açık veritabanı dosyası ve PAYLAŞILAN kilit almak. kilitleme "ORTAK" hakkında

belgelerine başka devletler:

veritabanı okumak ama yazılmamış olabilir. Herhangi bir sayıda işlem aynı anda SHARED kilitleri tutabilir, dolayısıyla birçok eşzamanlı okuyucu olabilir. Ancak bir veya daha fazla SHARED kilit aktifken başka bir iş parçacığı veya işlem veritabanı dosyasına yazılmasına izin verilmez.

FAQ devletler:

Çoklu işlemler aynı anda açık aynı veritabanını sahip olabilir. Birden çok süreç aynı anda SELECT yapabilir. Ancak, yalnızca bir süreç veritabanında zaman içinde herhangi bir anda değişiklik yapabilir.

kitap The Definitive Guide to SQLite devletler:

... bir bağlantı pragma read_uncommited kullanarak bir salt kararsız yalıtım düzeyine sahip tercih edebilirsiniz. true olarak ayarlanmışsa, bağlantı okunan tablolara okuma kilitleri koymaz. Bu nedenle, başka bir yazar, okuma-alınmamış moddaki bağlantı başka bir bağlantı tarafından engellenemez ya da engellenemeyeceğinden bir tabloyu değiştirebilir.

PRAGMA read_uncommitted = 1; 
SELECT Column1, Column2 FROM MyTable 

hala bir "veritabanı ile başarısız farklı bir bağlantı kullanarak aynı iş parçacığı üzerinde bir SQL güncelleştirme kilitlendi:

ben şöyle SQL sorgu komut ifadesi içindeki kararsız okumak için pragma belirlemeye çalıştı "istisna. Daha sonra bağlantı örneğinde okunamayan okuma düzeyini yalıtmaya çalıştım. Hala aynı istisna dışında değişiklik yok.

Veritabanını kilitlemeden veritabanında satırlar arasında geçiş yapmak için açık bir veri okuyucusuna sahip olmayı nasıl başarabilirim, böylece güncelleştirmeleri çalıştırabilir miyim?

Güncelleme:

işin altına Hem cevapları. Ancak, o zamandan beri, varsayılan geri alma günlüğünü kullanarak, veritabanı okumalarının ve yazmalarının geliştirilmiş eşzamanlılığını sağlayan Write-Ahead Günlüğü'nü kullanmaya başladım.

cevap

8

WAL modunu kullanın.

+0

. Http://sqlite.phxsoftware.com/ göre System.Data.SQLite.dll sürümü 1.0.66.0 18 Nisan 2010 ve SQLite sürümü 3.6.23.1 olduğunu. WAL kullanmak için 3.7+ sürümüne ihtiyacım var gibi görünüyor. Baska öneri? Güncelleştirilmiş bir ADO.Net sağlayıcısı var mı? – Elan

+0

Evet, bkz. Http://system.data.sqlite.org/index.html/doc/trunk/www/index.wiki sürüm 1.0.68.0 Şubat 2011, SQLite 3.7.5 –

+0

ile bir kod birleştirme olduğunu umut verici görünüyor; maalesef henüz indirilmeye hazır veya hazır bir şey görmedim ... Bu sürüm 1.0.68.0 resmi olarak kullanılabilir mi, yoksa bu bir alfa/beta mı? – Elan

2

Bu açık kaynak veri sağlayıcıyı here kullanarak çalışmaya çalıştıramadı. Ancak, dotConnect'un ücretsiz Standard Edition'ı kullanarak şu şekilde çalışabildim:

SQLite için paylaşılan önbelleği etkinleştirebilmemiz için aşağıdaki DLL dosyasını içe aktarın. Paylaşılan önbelleği etkinleştirmek için yukarıdaki işlevi yürütün. Yürütme önbelleğini etkinleştirmek için yukarıdaki işlevi çalıştırın. Not, bu sadece tüm süreç için bir kez gerçekleştirilmelidir - bkz. SQLite documentation. aşağıdaki gibi

sqlite3_enable_shared_cache(1); 

Sonra Pragma deyimi ile veri okuyucu tarafından kullanılan SQL sorgusu deyimini önüne: Veri okuyucu etkinken

PRAGMA read_uncommitted = 1; 
SELECT Column1, Column2 FROM MyTable 

biri şimdi serbestçe satırları güncelleştirmek ve ekleyebilirsiniz. Paylaşılan önbellekteki ek SQLite belgeleri here bulunabilir.

Güncelleme:

devart SQLite veri sağlayıcısına daha yeni bir sürümü artık gelişmiş bir şekilde bu destekler. aşağıdaki gibi kararsız örneğin bağlantı dizesine okur yapılandırabilirsiniz

Devart.Data.SQLite.SQLiteConnection.EnableSharedCache(); 

Bir:: biri aşağıdaki arama yapabilirsiniz paylaşılan önbellek etkinleştirmek için ben ADO.Net kullanıyorum

Devart.Data.SQLite.SQLiteConnectionStringBuilder builder = new SQLiteConnectionStringBuilder(); 
builder.ReadUncommitted = true; 
builder.DateTimeFormat = Devart.Data.SQLite.SQLiteDateFormats.Ticks; 
builder.DataSource = DatabaseFilePath; 
builder.DefaultCommandTimeout = 300; 
builder.MinPoolSize = 0; 
builder.MaxPoolSize = 100; 
builder.Pooling = true; 
builder.FailIfMissing = false; 
builder.LegacyFileFormat = false; 
builder.JournalMode = JournalMode.Default; 
string connectionString = builder.ToString(); 
İlgili konular