2009-11-26 4 views
3

При использовании ADO.NET (возможно, я ошибаюсь, я не знаю, как его называют), я замечаю, что могу только начать транзакцию с соединением, а команда, похоже, имеет команду. Транзакция, которая получает мне данные транзакции, но не запускает самой транзакции? На самом деле, смотря, я вижу это в System.Data.SQLitesqlite поддерживает только 1 транзакцию?

// Summary: 
    //  The transaction associated with this command. SQLite only supports one transaction 
    //  per connection, so this property forwards to the command's underlying connection. 
    [Browsable(false)] 
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
    public SQLiteTransaction Transaction { get; set; } 

Итак, SQLite поддерживает только один период транзакции? я попытался открыть другое соединение, но затем моя транзакция бросила исключение из-за блокировки БД. Так что у меня не может быть больше одного соединения одновременно?

ответ

4

Одна транзакция за соединение, да, но у нее может быть несколько соединений (каждая со своей активной транзакцией).

Обновление: интересное. Я не знал о режиме общего кэша. Если ваше соединение использует этот режим, для всех подключений, использующих один и тот же общий кэш, доступна только одна транзакция. См. SQLite shared-cache mode.

+0

Это не совсем так. Режим общего кэша не влияет на количество транзакций. Когда общий кэш отключен, каждое соединение с базой данных должно блокировать файл базы данных исключительно для записи на него. Таким образом, для всех подключений доступна только одна транзакция записи. Тем не менее, в режиме общего кэша блокировка выполняется для каждой таблицы для всех потоков внутри процесса. В любом режиме чтение может выполняться параллельно. – jowo

1

Я не уверен в нескольких подключениях, вероятно, это связано с тем, что соединение блокирует файл, поскольку SQLite является файловым DB, а не серверной базой данных (на базе сервера DB сервер сохраняет все файлы заблокированными и имеет дело с параллельными соединениями).

У вас может быть только одна транзакция OPEN за раз. Это должно быть интуитивно понятным, поскольку все, что происходит после того, как вы начали транзакцию, находится в этой транзакции, пока не будет rollback или commit. Затем вы можете запустить новый. SQLite требует, чтобы вся команда была в транзакции, поэтому, если вы не вручную открываете новую, она сделает это за вас.

Если вы беспокоитесь о вложенных транзакциях, вы можете подделать их с помощью savepoint. Documentation

1

В течение 1 транзакции вы можете читать/писать только до 1 соединения, пока транзакция не будет выполнена. Поэтому вы должны передать объект соединения, если вы делаете бизнес-операцию, которая охватывает несколько операторов SQL, как это:

public class TimeTableService 
    { 
     ITimeTableDataProvider _provider = new TimeTableDataProvider(); 

     public void CreateLessonPlanner(WizardData wizardData) 
     { 
      using (var con = _provider.GetConnection()) 
      using (var trans = new TransactionScope()) 
      { 
       con.Open(); 

       var weekListA = new List<Week>(); 
       var weekListB = new List<Week>(); 

       LessonPlannerCreator.CreateLessonPlanner(weekListA, weekListB, wizardData); 

       _provider.DeleteLessonPlanner(wizardData.StartDate, con); 

       _provider.CreateLessonPlanner(weekListA, con); 
       _provider.CreateLessonPlanner(weekListB, con); 

       _provider.DeleteTimeTable(TimeTable.WeekType.A, con); 
       _provider.StoreTimeTable(wizardData.LessonsWeekA.ToList<TimeTable>(), TimeTable.WeekType.A, con); 

       _provider.DeleteTimeTable(TimeTable.WeekType.B, con); 
       _provider.StoreTimeTable(wizardData.LessonsWeekB.ToList<TimeTable>(), TimeTable.WeekType.B, con); 

       trans.Complete(); 
      } 
     } 
    } 

соединительные и transactoin ресурсов автоматически освобождаться/закрыто с использованием-выпиской.

В каждом DataProvider метода вы тогда делают

класс
using(var cmd = new SQLiteCommand("MyStatement",con) 
{ 
    // Create params + ExecuteNonQuery 
} 

TransactionScope новый в .NET 3.5 и делает автоматически откат, если происходит исключение. Простота управления ...

Смежные вопросы