领域数据同步不一致

2023-12-03

我遇到一个问题,每次执行相同的查询时,Realm 有时会返回不同的数据。目前我正在使用 SyncAdapter 进行上传。我们的想法是尝试实现离线模式。

因此,当用户创建一个项目时,它会被添加到领域数据库中。我通过获取 maxId 并向其添加 1000 来手动生成该项目的 ID。之后,我将 itemID 发送到 UploadSyncAdapter,在其中获取 itemById 并将其发送到后端,后端返回具有真实 ID 的项目。因此,之后我删除旧项目并将新项目插入领域。

在我返回并读取数据后,它每秒返回一个大小为 115 数据的数组,另一次返回一个大小为 116 的数组。我什至使用调试器通过 ID 搜索该项目,它确实一次找到了该项目,第二次却没有。但看起来在我重建项目后,该项目就在那里并且可以正常工作,或者如果我使用即时运行重新运行应用程序。

任何帮助表示赞赏...

UPDATE顺便说一句,我正在使用 RXjava 从服务器获取数据,但它正在当前线程(SyncAdapter 线程)上订阅和观察。

这是代码:

@Override
public void onNext(TaskResponse taskResponse) {
     tasksDatabaseManager.deleteTaskById(taskId);
     List<Task> tasks = taskResponse.getTaskDataList();
     tasksDatabaseManager.insertTasks(tasks);
 }

public void deleteTaskById(int taskId){
    Realm realm = Realm.getDefaultInstance();
    realm.beginTransaction();
    RealmResults<Task> rows = realm.where(Task.class).equalTo(ID, taskId).findAll();
    rows.deleteAllFromRealm();
    realm.commitTransaction();
    realm.close();
}

private void copyOrUpdateTasks(List<Task> tasksList){
    Realm realm = Realm.getDefaultInstance();
    ArrayList<Task> updatedTaskList;
    //first initialize task permissions
    updatedTaskList = filterTasksByPermission(tasksList);
    //initialize custom task data
    for (Task task : updatedTaskList) {
        initializeTaskCustomFields(task);
    }
    //save new data
    Log.d(TAG, "tasks number before update: " + getTasks().size());
    realm.beginTransaction();
    realm.copyToRealmOrUpdate(updatedTaskList);
    realm.commitTransaction();
    realm.close();

    Log.d(TAG, "tasks number after update: " + getTasks().size());
}

在 filterTasksByPermission 中,我只是计算任务的一些权限,但任务正在列表中返回。在initializeTaskCustomFields中,我也只是在保存到Realm之前计算对象的2个字段(这样我也将这些值保存在Realm中)


经过一番研究,我发现了问题所在。但如果我错了,请纠正我。我在 Rx 调用中将 Subscribers.io() 替换为 Subscribers.newThread(),现在它工作正常。所以我的理论是:

在调用我的 UploadAdapter 上传更改的数据之前,我使用带有 Subscribers.io() 的 Rx 调用将我的项目插入数据库中。 Subscribers.io() 使用线程池来重用线程,或者在必要时创建新线程。假设它生成了一个名为“A”的线程。线程 A 获取一个 Realm 实例(假设 Realm 快照为“1”)并将创建的项目插入其中。在调用 SyncAdapter 后,它还会获得一个具有相同 Realm 快照“1”的新 Realm 实例。 SyncAdapter 完成将数据上传到服务器后,它会删除旧项目,并插入从服务器获取的新项目。因此,在此 Realm 数据发生更改后,最新的 Realm 快照现在为“2”。 SyncAdapter 向 Activity 发送广播,表明上传已完成,并且应该从 Realm 数据库获取新数据。

为了从 Realm 读取数据,我还使用 Rx 和 Subscribers.io()。因此,当从 Realm 请求新数据时,Subscribers.io() 的池中已经有一个线程正在等待重用,这就是线程“A”。而且由于这个线程是一个非Looper线程,它不知道Realm数据发生了变化,并且它仍然使用Realm快照“1”,所以这就是我从Realm获取旧数据的原因。刷新几次后 Subscribers.io() 可能会创建一个新线程,假设线程“B”。

所以线程“B”也得到了一个领域快照,这次它是最新的快照,所以快照“2”。它返回正确的数据。

因此,当使用 Subscribers.newThread() 时,它始终会创建一个新线程,并且始终具有最新的 Realm 快照。

以下是有关 Subscribers.io() 和 Subscribers.newThread() 之间差异的链接:使用 Rxjava Schedulers.newThread() 与 Schedulers.io() 进行改造

希望这对某人有帮助!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

领域数据同步不一致 的相关文章

随机推荐

  • 如何转换 FParsec 解析器来解析空格

    我正在实现一个解析器 它使用 FParsec 将注释视为空白 看起来它需要一个简单的解析器转换 但我还不知道如何实现它 这是我试图进行类型检查的代码 let whitespaceTextChars t r n Read whitespace
  • 从c#中的excel文件中读取列名

    我必须实现文件上传功能 允许用户上传包含表格数据的文件 上传文件时我想找到表的列名 我怎样才能做到这一点 vc 74我想指出代码中的一些错误 而不是有sheetColumns Rows 应该有sheetColumns Columns因为它已
  • 即使使用缓存控制,来自云端的 RefreshHit:max-age=0,无存储

    Cloudfront 正在为根本不应该缓存的请求获取 RefreshHit 它不应该被缓存 因为 It has cache control max age 0 no store 最小 TTL 为 0 和 我创建了多个失效 在 所以这个缓存的
  • 出现异常:java.util.ServiceConfigurationError

    运行我的应用程序时出现以下异常 我正在使用jboss 5 1 1和jdk 1 6 01 50 04 828 ERROR HelloWorld Servlet service for servlet HelloWorld threw exce
  • 加载 rgdal 时出错

    我已经成功安装了rgdal与依赖项 GDAL 和 Proj4 一起打包 安装后我成功地将包加载到R中library功能 但是 在我最近一次登录后 当我输入命令时library rgdal 我收到一条错误消息 Error package or
  • 如何使用 IronRuby 的 ErrorListener

    我有一个 C 程序来执行 IronRuby 脚本 但在这样做之前 我想先编译该文件 看看是否有任何错误 但ErrorListener 似乎不能很好地工作 我的代码有什么问题吗 class Program static void Main s
  • 什么线程调用 silverlight WCF 调用上的已完成事件处理程序?

    假设我有 Silverlight 应用程序调用 WCF 服务 void DoStuff MyProxy proxy new MyProxy proxy DoStuffCompleted DoStuffCompleted proxy DoSt
  • 如何在谷歌地图中显示两个地理坐标之间的路线? [复制]

    这个问题在这里已经有答案了 可能的重复 J2ME Android BlackBerry 行车路线 两个位置之间的路线 我只是编写一个应用程序 用于在谷歌地图视图中显示两个坐标 经纬度 之间的路线 显示单个坐标 即使有标记 效果很好 但如何用
  • 从 Windows 服务加载 GUI 应用程序

    我正在编写一个 NET Windows 服务 其作用是启动 GUI 应用程序 其源不可用 该操作是即发即忘 除了初始命令行参数之外没有任何通信 该服务应该作为给定的 Windows 帐户运行 问题 服务启动的应用程序是not显示在桌面上 它
  • HTTP 状态 500 - java.lang.ClassNotFoundException:org.apache.jsp.index_jsp

    我在 Eclipse 中创建了一个 JSP 项目 使用 Tomcat 7 但是当我运行该页面时 我得到一个 ClassnotFoundExcption 在我的项目中 我使用控制器将数据绑定到 JSP 我有一个控制器 一个服务和一个数据对象
  • 致命错误:在非对象上调用成员函数 rowCount()

    我在登录中使用 PDO 按照之前通过 sqli 的指示 并且我已经尝试了以下操作 但是我收到了此致命错误 并且无法弄清楚要提供什么 因此它满足了错误 if query gt rowCount gt 0 session stuff refre
  • 放大二维 UICollectionView

    我创建了一个UICollectionView这是水平和垂直的 它有不同的UICollectionViewCells 一切都布置正确 现在我正在努力做到zoomable The UICollectionViewCells也正确调整了大小 每次
  • 一般解析字符串到日期

    我正在与 Web 服务通信 并且 json 响应中包含日期 问题是这些日期的格式不同 有没有通用的方法来解析这些字符串 您可能应该有一个有序的格式列表来尝试 最好使用乔达时间作为一个比内置 API 好得多的 API 然后依次尝试每个 API
  • Alexa 帐户链接 - “帐户链接凭据无效”

    我正在创建带有帐户链接的 Alexa 技能 我获得了链接授权码并将其兑换为访问令牌 然后 我尝试将所有参数 代码 访问令牌 技能 ID 放入 Alexa Skill Activation API 中 我总是收到一条消息 帐户链接凭据无效 v
  • 更新jar中的.class文件

    我想更新一个 class文件在一个jar与一个新的 最简单的方法是什么 尤其是在 Eclipse IDE 中 本教程详细说明如何更新 jar 文件 jar uf jar file
  • 从 VS2008 升级到 VS2010 后,Web 安装项目删除文件

    我有一个使用 VS2008 构建的 Web 设置项目 我已经将我的解决方案转换为 VS2010 现在当我构建新的安装程序并从 MSI 运行安装时 它安装得很好 然后在最后一步 删除刚刚安装的所有文件 我已将RemovePreviousVer
  • 如何使用inst/extdata中的文件? R 包检查阻止在 R 3.6 中使用 system.file()

    我正在编写 R 包并尝试使用外部文件 我把它放在inst extdata并使用system file extdata file csv package mypackage 在我的函数中加载文件 官方手册只描述了这种获取数据的方式inst e
  • Spring应用程序似乎没有持久化数据

    我正在尝试将一些内容写入我的数据库 但尽管它报告 成功完成请求 但它不起作用 成功后 一切似乎都工作正常 我的控制器正确地重定向了我 Debug DEBUG a d p payment PaymentServiceImpl Requesti
  • 如何让 slickgrid div 根据表格大小调整大小

    我希望我们有一些熟悉 slickGrid 的用户也能看到 StackOverflow 如何使用它 我有一个包含 slickGrid 的 HTML 如下所示 div style width 600px margin 25px 0 0 0 di
  • 领域数据同步不一致

    我遇到一个问题 每次执行相同的查询时 Realm 有时会返回不同的数据 目前我正在使用 SyncAdapter 进行上传 我们的想法是尝试实现离线模式 因此 当用户创建一个项目时 它会被添加到领域数据库中 我通过获取 maxId 并向其添加