java - 面对事务时使用 "last modified"时间戳同步 Oracle 数据库

标签 java database oracle synchronization timestamp

我们有一个企业级 Oracle 12c 数据库,我们希望使用 Java 程序(将在同步期间进行大量聚合)与分析数据库同步,并使用每行“上次修改时间” Oracle 数据库中的时间戳来确定需要同步哪些行。通用算法为

void run() {
  Timestamp lastRead = loadLastRead(); // load last logged timestamp
  while(true) {
    rows = select * from Oracle database where last_modified >= lastRead;
    lastRead = rows.max(last_modified); // max timestamp from the retrieved rows
    saveLastRead(lastRead); // log the timestamp in case the program crashes
    sleep(five minutes or whatever);
  }
}

我担心我可能会遇到以下情况:

  1. 事务从 R1 行开始,计算 T1 的时间戳
  2. 写入 R2 行的last_modified 时间戳 T2
  3. 使用 T0 的 LastRead 进行同步
  4. 同步结束,lastRead 更新为 T2
  5. 事务在 R1 行上提交,时间戳为 T1 < T2

现在我永远不会同步行 R1(直到新数据写入其中,假设我没有再次被事务阻止)。我可以尝试最小化时间戳偏差,但我没有找到消除它的方法。

一种解决方案是执行类似的操作

lastRead = rows.max(last_modified) - C;

其中 C 是五秒或其他一些我们认为许多事务不会超过的时间跨度 - 问题是,如果 C 太大,我们将重新同步太多数据,而如果 C 太小,我们将重新同步太多数据。 C 我们可能会得到一些超过 C 的异常交易

另一种解决方案是使用每行版本号,这需要大量的簿记工作,并且几乎肯定会损害 select * from Oracle Database

最佳答案

确实,尝试使用基于时间戳列的查询并不是获取更改的可靠方法,除非您引入显着的延迟或系统停机时间(例如,当不太可能进行并发更改时运行过夜批处理) )。

一些人使用的另一种方法是使用基于 ORDERed Oracle 序列的单调递增数字 ID 列。这种方法的一个问题可能是有序序列在 RAC 系统中的执行方式。

一个Materialized View (正如 Lalit 所建议的)是一种选择。

根据您的预算和要求的复杂性,其他一些选项包括:

注意:GoldenGate 和 ODI 是互补产品,可以很好地协同工作。

关于java - 面对事务时使用 "last modified"时间戳同步 Oracle 数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27285371/

相关文章:

java - Jersey : JSON Unsupported Media Type

java - 使用 Jackson 和 JavaTimeModule 序列化 Java 8 ZonedDateTime

mysql - 如何停止和启动mysql?

java.lang.ClassCastException : oracle. sql.ARRAY 无法转换为 oracle.sql.ARRAY

sql - 尽管缺少分析值,但完整的日期时间列表

sql - Oracle SQL 查询按组获取剩余金额

java - 在java中使用正则表达式捕获重复的数字组

java - Spring - 调用了错误的方法

sql - 如何在 SQL 中四舍五入

php - 向自定义 WordPress 数据库表中的文本字段添加新行,而不覆盖现有值