SQLite支持跨多个数据库的事务吗?

10
我已经进行了一些搜索,也阅读了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的最新版本。
更新:还有一个问题--这是否是人们通常会添加到他们的单元测试中的内容?我总是对数据库进行单元测试,但从未遇到过这种情况。如果是这样,你会怎么做?它几乎像你需要向该方法传递另一个参数,例如bool test_transaction,并且如果为true,在数据库访问之间引发异常。然后在调用后进行测试,以确保第一组数据没有进入另一个数据库。但也许这是由SQLite测试覆盖的内容,不应出现在我的测试用例中。

1
我认为你不想将这个添加到单元测试中。如果事务正常工作,就没有必要一遍又一遍地测试它们。只需进行一些初始测试,以确保插入、更新、回滚等操作是正确的,然后你就可以继续了。 - A G
好的,我也觉得这是最好的选择。完美! - Dave
2个回答

14

是的,事务可以在不同的SQLite数据库之间甚至在SQLite和SQL Server之间进行。我尝试过几次。

以下是一些链接和信息:

来自此处 - 在不同数据源之间执行事务

由于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();

}

我仍然需要编写代码来执行跨多个数据库的事务,但我接近验证它了! :) - Dave
该链接已损坏。 - Brian Minton
@BrianMinton 已更新,附带 archive.org 链接。原始链接已失效(404)。 - A G

3

是的,SQLite明确支持多数据库事务(有关技术细节,请参见https://www.sqlite.org/atomiccommit.html#_multi_file_commit)。 但是,有一个相当大的警告。 如果数据库文件处于WAL模式,则:

涉及对多个ATTACHed数据库进行更改的事务对于每个单独的数据库是原子的,但对于所有数据库作为集合而言则不是。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接