【开发问题记录】01—大量数据同时插入数据库导致的时间戳重复问题

需求背景
用户登录之后将其云端收藏的内容同步到本地数据库且保持和原收藏顺序一致, 比如在电脑上登录之后显示的收藏顺序A->B->C 切换到手机登录之后的顺序预期也是A->B->C, 之后的查询就可以不依赖云端接口而是直接查本地数据库

代码抽象
针对这个场景我们抽象出来一段 伪代码

 fun test() {
        // list是云端服务器返回的数据 按照顺序 ABC
        val list = mutableListOf<String>("A", "B", "C")
        list.forEach{
            // 本地数据库插入这条记录和 对应的更新时间, 以便后续查询的时候可以直接读取数据库
            dao.insertItem(it,System.currentTimeMillis())
        }
    }

看起来没有什么问题吧? 插入一条就更新本条的时间戳~

实际上遇到了坑——时间戳重复

2023-07-30 23:11:12.601  9952-9952    A time = 1690729872601
2023-07-30 23:11:12.601  9952-9952    B time = 1690729872601
2023-07-30 23:11:12.601  9952-9952    C time = 1690729872601

数据库插入的操作执行地很快导致 多条记录在同一ms内执行, 当你再去查询数据库的收藏顺序时就无法保证一定是按照ABC返回的

解决办法
1 下标去重法 推荐指数 5颗星 ⭐️⭐️⭐️⭐️⭐️

val list = mutableListOf<String>("A", "B", "C")
val time = System.currentTimeMillis()
list.forEachIndexed { index, s ->
    Log.i("TAG", "$s time = ${time + index}")
 }
2023-07-30 23:21:13.927 11181-11181   A time = 1690730473927
2023-07-30 23:21:13.927 11181-11181   B time = 1690730473928
2023-07-30 23:21:13.927 11181-11181   C time = 1690730473929

2 延时去重法 推荐指数 1颗星 ⭐️
空耗cpu性能1ms 极端条件下考虑

fun test() {
    val list = mutableListOf<String>("A", "B", "C")
    list.forEachIndexed { index, s ->
            Thread.sleep(1)
            Log.i("TAG", "$s time = ${System.currentTimeMillis()}")
        }
    }
2023-07-30 23:29:01.444 11997-11997   A time = 1690730941444
2023-07-30 23:29:01.445 11997-11997   B time = 1690730941445
2023-07-30 23:29:01.446 11997-11997   C time = 1690730941446

3 纳秒去重法 推荐指数 2颗星 ⭐️⭐️
因为获取纳秒本身就是一个消耗性能的方式, 因此也不推荐

fun test() {
        val list = mutableListOf<String>("A", "B", "C")
        list.forEachIndexed { index, s ->
            val nTime = System.nanoTime()
            Log.i("TAG", "$s time = $nTime")
        }
    }
2023-07-30 23:26:30.382 11810-11810   A time = 1809472049499997
2023-07-30 23:26:30.382 11810-11810   B time = 1809472049659074
2023-07-30 23:26:30.382 11810-11810   C time = 1809472049687304

也可以从数据库的查询上考虑如何解决: 时间戳相同的情况下,如何自定义返回顺序。这个我还没有研究明白,欢迎大家补充。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值