1

我有一个 Xamarin Android 项目并且正在使用 mono.data.sqlite 并且遇到了多线程问题,所以我尝试了 Zumero 组件。我仍然有问题。我正在尝试使用http://www.sqlite.org/threadsafe.html中的标志 SQLITE_CONFIG_SERIALIZED 设置序列化模式。我仍然遇到随机崩溃。我可以用 Zumero 设置序列化标志吗?除了从源代码重新编译 SQLite 之外,还有什么其他建议吗?

谢谢,

布赖恩

4

1 回答 1

0

我曾经有这个问题。尽管有相互矛盾的建议,但我是如何停止获得例外的:

在所有线程之间共享 SQLiteConnection 的静态实例。这是安全的,因为 SQLite 连接只是一个文件指针,它不像传统的数据连接。

将我的所有 SQLite 查询/插入/更新包装在一个互斥锁中,并将我的 SQLiteConnection 的 statix 实例作为锁。有人建议我在使用序列化模式时不需要这样做,但是我对它的体验会有所不同。

lock(myStaticConnection) {
   myStaticConnection.Query<Employee>("....");
}

作为备份,我还使用一些添加的重试逻辑来封装每个查询。不确定 SQLite 是否自行执行此操作(我已经看到对 busytimeout 的引用并且人们声称它现在已经消失了?)。像这样的东西:

    public static List<T> Query<T> (string query, params object[] args) where T : new()
    {
        return Retry.DoWithLock (() => {
            return Data.connection.Query<T> (query, args);
        }, Data.connection, 0);
    }

    public static T DoWithLock<T>(
        Func<T> action,
        object lockable,
        long retryIntervalTicks = defaultRetryIntervalTicks,
        int retryCount = defaultRetryCount)
    {
        return Do (() => {
            lock (lockable) {
                return action();
            }
        });
    }

    public static T Do<T>(
        Func<T> action,
        long retryIntervalTicks = defaultRetryIntervalTicks,
        int retryCount = defaultRetryCount)
    {
        var exceptions = new List<Exception> ();

        for (int retry = 0; retry < retryCount; retry++) {
            try{
                return action();
            } catch (Exception ex) {
                exceptions.Add (ex);
                ManualSleepEvent (new TimeSpan(retryIntervalTicks));
            }
        }

        throw new AggregateException (exceptions);
    }
于 2014-09-27T14:15:42.007 回答