SQLite WP 8.1中多线程环境中的事务

时间:2015-03-09 06:43:38

标签: multithreading sqlite transactions windows-phone-8.1

我在使用SQLite时遇到以下情况。

有两个线程正在处理数据库。

两个线程都必须在事务中插入消息。

因此,如果说一个线程在插入20k行后提交,而其他线程尚未提交。

在输出中,我看到所有已提交的数据已被线程2插入,直到线程1提交数据为止。

示例功能:

    /// <summary>
    /// Inserts list of messages in message table
    /// </summary>
    /// <param name="listMessages"></param>
    /// <returns></returns>
    public bool InsertMessages(IList<MessageBase> listMessages, bool commitTransaction)
    {
        bool success = false;

        if (listMessages == null || listMessages.Count == 0)
            return success;

        DatabaseHelper.BeginTransaction(_sqlLiteConnection);


        foreach (MessageBase message in listMessages)
        {
            using (var statement = _sqlLiteConnection.Prepare(_insertMessageQuery))
            {

                BindMessageData(message, statement);

                SQLiteResult result = statement.Step();
                success = result == SQLiteResult.DONE;


                if (success)
                {
                    Debug.WriteLine("Message inserted suucessfully,messageId:{0}, message:{1}", message.Id, message.Message);
                }
                else
                {
                    Debug.WriteLine("Message failed,Result:{0}, message:{1}", result, message.Message);
                }
            }
        }
        if (commitTransaction)
        {
            Debug.WriteLine("Data committed");
            DatabaseHelper.CommitTransaction(_sqlLiteConnection);
        }
        else
        {
            Debug.WriteLine("Data not committed");
        }

        return success;
    }

有没有办法阻止线程2插入的提交事务?

1 个答案:

答案 0 :(得分:0)

简而言之,单个数据库无法实现。

单个sqlite数据库不能有多个具有单独事务上下文的同时写入程序。 sqlite数据库每个连接也没有单独的上下文;要获取上下文,您需要建立新连接。但是,只要使用insert(或update / delete)启动初始写入,事务就需要对数据库执行RESERVED锁定(允许读取器,不允许其他编写器),这意味着无法进行并行写入。我认为您可以使用SAVEPOINTRELEASE伪造它,但这些也是在连接上序列化的,并且不会生成单独的上下文。

考虑到这一点,只要两个线程都没有写入同一个表,您就可以使用使用ATTACH DATABASE连接的单独数据库。为此,您将在运行时附加包含其他表的附加数据库。但是,您仍然需要为每个并行编写器提供单独的连接,因为提交连接仍然适用于所有打开的事务。

否则,您可以通过打开其他连接和后续连接来获得单独的交易。事务只需要等到RESERVED锁被释放。

参考文献: