Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
İşlemler, birden çok SQL deyimini tek bir atomik birim olarak veritabanına kaydedilmiş tek bir iş birimi halinde gruplandırmanıza olanak tanır. İşlemdeki herhangi bir ifade başarısız olursa, önceki ifadeler tarafından yapılan değişiklikler geri alınabilir. İşlemin başlatıldığı veritabanının ilk durumu korunur. Bir işlem kullanmak, veritabanında aynı anda çok sayıda değişiklik yaparken SQLite performansını da artırabilir.
Eşzamanlılık
SQLite'te, veritabanında bekleyen değişikliklere sahip olmasına izin verilen aynı anda yalnızca bir işlem vardır. Bu nedenle, başka bir işlem tamamlanmakta çok uzun sürerse, BeginTransaction üzerindeki Execute ve SqliteCommand yöntemlerine yapılan çağrılar zaman aşımına uğrayabilir.
Kilitleme, yeniden denemeler ve zaman aşımları hakkında daha fazla bilgi için bkz . Veritabanı hataları.
Yalıtım düzeyleri
İşlemler SQLite'te varsayılan olarak serileştirilebilir . Bu yalıtım düzeyi, bir işlem içinde yapılan tüm değişikliklerin tamamen yalıtılmış olduğunu garanti eder. İşlem dışında yürütülen ifadeler, işlemin değişikliklerinden etkilenmez.
SQLite, paylaşılan önbellek kullanılırken okunmamış okumayı da destekler. Bu düzey kirli okumalara, güncelleştirilemeyen okumalara ve hayaletlere izin verir:
Bir işlemde bekleyen değişiklikler işlemin dışındaki bir sorgu tarafından döndürülür ancak işlemdeki değişiklikler geri alındığında kirli bir okuma gerçekleşir. Sonuçlar, veritabanına hiçbir zaman işlenmeyen veriler içerir.
Bir işlem aynı satırı iki kez sorguladığında güncelleştirilemeyen bir okuma gerçekleşir, ancak sonuçlar farklı olur çünkü iki sorgu arasında başka bir işlem tarafından değiştirildi.
Hayaletler, bir işlem sırasında sorgunun where koşulunu karşılamak için değiştirilen veya eklenen satırları ifade eder. İzin verilirse, aynı sorgu aynı işlemde iki kez yürütülürken farklı satırlar döndürebilir.
Microsoft.Data.Sqlite, 'a geçirilen IsolationLevel'i BeginTransaction en düşük düzey olarak kabul eder. Gerçek yalıtım düzeyi, ya onaysız okuma ya da serileştirilmiş olarak yükseltilecektir.
Aşağıdaki kod, kirli bir okumanın benzetimini yapar. Bağlantı dizesinin içermesi Cache=Sharedgerektiğini unutmayın.
using (var firstTransaction = firstConnection.BeginTransaction())
{
var updateCommand = firstConnection.CreateCommand();
updateCommand.CommandText =
@"
UPDATE data
SET value = 'dirty'
";
updateCommand.ExecuteNonQuery();
// Without ReadUncommitted, the command will time out since the table is locked
// while the transaction on the first connection is active
using (secondConnection.BeginTransaction(IsolationLevel.ReadUncommitted))
{
var queryCommand = secondConnection.CreateCommand();
queryCommand.CommandText =
@"
SELECT *
FROM data
";
var value = (string)queryCommand.ExecuteScalar();
Console.WriteLine($"Value: {value}");
}
firstTransaction.Rollback();
}
Ertelenen işlemler
Microsoft.Data.Sqlite sürüm 5.0'dan itibaren işlemler ertelenebilir. Bu, ilk komut yürütülene kadar veritabanında gerçek işlemin oluşturulmasını erteler. Ayrıca, işlemin bir okuma işleminden komutlarının gerektirdiği şekilde aşamalı olarak bir yazma işlemine yükseltmesine neden olur. Bu işlem sırasında veritabanına eşzamanlı erişimi etkinleştirmek için yararlı olabilir.
using (var transaction = connection.BeginTransaction(deferred: true))
{
// Before the first statement of the transaction is executed, both concurrent
// reads and writes are allowed
var readCommand = connection.CreateCommand();
readCommand.CommandText =
@"
SELECT *
FROM data
";
var value = (long)readCommand.ExecuteScalar();
// After a the first read statement, concurrent writes are blocked until the
// transaction completes. Concurrent reads are still allowed
var writeCommand = connection.CreateCommand();
writeCommand.CommandText =
@"
UPDATE data
SET value = $newValue
";
writeCommand.Parameters.AddWithValue("$newValue", value + 1L);
writeCommand.ExecuteNonQuery();
// After the first write statement, both concurrent reads and writes are blocked
// until the transaction completes
transaction.Commit();
}
Uyarı
Ertelenen işlem içindeki komutlar, veritabanı kilitliyken işlemin okuma işleminden yazma işlemine yükseltilmesine neden olursa başarısız olabilir. Böyle bir durumda uygulamanın tüm işlemi yeniden denemesi gerekir.
Kayıt noktaları
Microsoft.Data.Sqlite sürüm 6.0, kayıt noktalarını destekler. İç içe işlemler oluşturmak için kurtarma noktaları kullanılabilir. Kayıt noktaları, işlemin diğer bölümleri etkilenmeden geri alınabilir ve bir kayıt noktası işleme alınıp serbest bırakılmış olsa bile, ana işlemin bir parçası olarak yapılan değişiklikler daha sonra geri alınabilir.
Aşağıdaki kod, eşzamanlı güncelleştirmeleri algılamak ve daha büyük bir işlemin parçası olarak bir kayıt noktası içindeki çakışmaları çözmek için İyimser Çevrimdışı Kilit düzeninin kullanılmasını gösterir.
using (var transaction = connection.BeginTransaction())
{
// Transaction may include additional statements before the savepoint
var updated = false;
do
{
// Begin savepoint
transaction.Save("optimistic-update");
var insertCommand = connection.CreateCommand();
insertCommand.CommandText =
@"
INSERT INTO audit
VALUES (datetime('now'), 'User updates data with id 1')
";
insertCommand.ExecuteScalar();
var updateCommand = connection.CreateCommand();
updateCommand.CommandText =
@"
UPDATE data
SET value = 2,
version = $expectedVersion + 1
WHERE id = 1
AND version = $expectedVersion
";
updateCommand.Parameters.AddWithValue("$expectedVersion", expectedVersion);
var recordsAffected = updateCommand.ExecuteNonQuery();
if (recordsAffected == 0)
{
// Concurrent update detected! Rollback savepoint and retry
transaction.Rollback("optimistic-update");
// TODO: Resolve update conflicts
}
else
{
// Update succeeded. Commit savepoint and continue with the transaction
transaction.Release("optimistic-update");
updated = true;
}
}
while (!updated);
// Additional statements may be included after the savepoint
transaction.Commit();
}