Поддерживает ли SQLite транзакции между несколькими базами данных? - PullRequest
9 голосов
/ 21 апреля 2010

Я провел некоторый поиск, а также прочитал FAQ на сайте SQLite, но мне не повезло найти ответ на мой вопрос.

Вполне возможно, что мой подход к базе данных несовершенен, но в данный момент я хотел бы хранить свои данные в нескольких базах данных SQLite3, так что это означает отдельные файлы. Я очень беспокоюсь о повреждении данных из-за возможного сбоя приложения или перебоя в питании в процессе изменения данных в моих таблицах.

Чтобы обеспечить целостность данных, мне нужно сделать следующее:

begin transaction
modify table(s) in database #1
modify table(s) in database #2
commit, or rollback if error

Поддерживается ли это в SQLite? Кроме того, я использую sqlite.net, особенно последний, который основан на SQLite 3.6.23.1.

UPDATE

Еще один вопрос - это то, что люди обычно добавляют в свои юнит-тесты? Я всегда тестирую базы данных, но никогда не было такого случая. И если так, как бы вы это сделали? Это почти как если бы вы передавали в метод другой параметр, такой как bool test_transaction, и, если это так, генерируйте исключение между обращениями к базе данных. Затем проверьте после вызова, чтобы убедиться, что первый набор данных не попал в другую базу данных. Но, возможно, это то, что рассматривается в тестах SQLite, и в моих тестовых примерах должно отображаться , а не .

Ответы [ 2 ]

13 голосов
/ 21 апреля 2010

Да, транзакции работают с разными базами данных sqlite и даже между sqlite и sqlserver. Я пробовал это пару раз.

Некоторые ссылки и информация

Отсюда - Транзакция между различными источниками данных.

Поскольку поставщик SQLite ADO.NET 2.0 поддерживает зачисление транзакций, можно не только выполнять транзакции, охватывающие несколько источников данных SQLite, но и другие механизмы баз данных, такие как SQL Server.

Пример:

using (DbConnection cn1 = new SQLiteConnection(" ... ") )
using (DbConnection cn2 = new SQLiteConnection(" ... "))
using (DbConnection cn3 = new System.Data.SqlClient.SqlConnection( " ... ") )
using (TransactionScope ts = new TransactionScope() )
{
    cn1.Open(); cn2.Open(); cn3.Open();
    DoWork1( cn1 );
    DoWork2( cn2 );
    DoWork3( cn3 );
    ts.Complete();
}

Как прикрепить новую базу данных:

SQLiteConnection cnn = new SQLiteConnection("Data Source=C:\\myfirstdatabase.db");
cnn.Open();

using (DbCommand cmd = cnn.CreateCommand())
{
  cmd.CommandText = "ATTACH DATABASE 'c:\\myseconddatabase.db' AS [second]";
  cmd.ExecuteNonQuery();

cmd.CommandText = "SELECT COUNT(*) FROM main.myfirsttable INNER JOIN second.mysecondtable ON main.myfirsttable.id = second.mysecondtable.myfirstid";


  object o = cmd.ExecuteScalar();

}
1 голос
/ 24 августа 2018

Да, SQLite явно поддерживает транзакции с несколькими базами данных (технические подробности см. https://www.sqlite.org/atomiccommit.html#_multi_file_commit). Тем не менее, есть довольно большое предостережение. Если файл базы данных находится в режиме WAL , то:

Транзакции, связанные с изменениями в нескольких базах данных ATTACH. атомарны для каждой отдельной базы данных, но не атомарны во всех базы данных в виде набора.

...