当前位置: 首页 > 知识库问答 >
问题:

调用Record.update()时的数据变更异常?

督烨赫
2023-03-14

我想我错过了一些关于UpdatleRecord.update()如何工作的主要内容。

不起作用的示例代码

MailKeywordRealAddressRecord linkRecord = dsl.select().
  from(MAIL_KEYWORD_REAL_ADDRESS).
  where(MAIL_KEYWORD_REAL_ADDRESS.MAIL_KEYWORD_ID.eq(mailKeyword.getId())).
  fetchOneInto(MailKeywordRealAddressRecord.class);

if( linkRecord == null ){
  log.debug("no link record found for our mailKeyword");
  linkRecord = dsl.newRecord(MAIL_KEYWORD_REAL_ADDRESS);
  linkRecord.setMailKeywordId(mailKeyword.getId());
  linkRecord.setRealAddressId(realAddress.getId());

  linkRecord.insert();
}
else {
  // 1 - will geta "DataChangedException" because it tries to do a
  // "select ... for udpate" with the *new* realAddress id
  log.debug("updating old linkRecord from: {}", linkRecord );
  linkRecord.setRealAddressId(realAddress.getId());
  linkRecord.update();

  // 2 - working
  //      log.debug("updating old linkRecord from: {}", linkRecord );
  //      linkRecord.delete();
  //      linkRecord.setRealAddressId(realAddress.getId());
  //      linkRecord.insert();
}

这将导致异常

DataChangedException:数据库记录不再存在

如果我看一下SQL,JOOQ正在使用RealAddressId的新值发布一个Select for dateSQL语句。

如果我注释掉(1)块并使用(2)——JOOQ似乎做了我想做的事情,它会删除旧记录并更新新记录。

MailKeywordRealAddressRecord下面的表是一个普通的多对多链接表(两列,都声明为复合主键)。

想想看…-这就是问题所在吗?我正在更新主键列?我很乐意坚持使用delete/insert逻辑(或者我可以重构为直接的SQL语句)——只是想弄清楚到底发生了什么。

数据库为Postgres,JOOQ版本为3.10.1。

共有1个答案

慕容玉书
2023-03-14

您当前的逻辑可能会遇到竞争条件,并且通常有点太乏味而无法编写。jOOQ支持PostgreSQL的INSERT。。在CONFLICT DO UPDATE语法中,将upserts的处理委托给数据库,这通常是您更喜欢的,除非您真的依赖于乐观锁定,而在当前的代码示例中,您似乎没有这样做

我认为这只是因为误解了jOOQ的乐观锁定功能,另请参见手册:

  • https://www.jooq.org/doc/latest/manual/sql-building/dsl-context/custom-settings/settings-optimistic-locking
  • https://www.jooq.org/doc/latest/manual/sql-execution/crud-with-updatablerecords/optimistic-locking

有两种设置控制jOOQ乐观锁定功能的行为:

  • ExecuteOptimisticLocking:这允许完全关闭该功能
  • ExecuteWithoOptimisticLockingExcludeUnversioned:这允许关闭未明确版本化的可更新记录的功能

出于向后兼容的原因,这两个标志在默认情况下都是关闭的。如果启用了乐观锁定,那么默认情况下,可更新记录也会启用乐观锁定,这些记录没有明确配置版本字段。在这种情况下,在执行乐观锁定检查时,将验证整个记录。这可能不是您想要的,所以您应该将此标志设置为true

 类似资料:
  • 问题内容: 我正在尝试在jquery的AJAX调用中使用变量,但是它不起作用。移动变量包含不同的值。请检查以下代码: 建议在数据中使用$ move变量的任何方法。 问题答案: 它应该是

  • 我在尝试从SOAPUI调用服务时遇到以下异常。当我在浏览器中打开endpoint时,它会显示wsdl fine。 我的wsdl在was 7服务器中 我在中的Soap请求: 肥皂UI中的肥皂反应: 这就是我配置jaxws:endpoint的方式

  • 我回答这个是因为我无法找到一个解决我的具体情况的方法。

  • 这是我的客户端代码 这是我的Rest控制器代码: 如果我在调用后使用 String.class 作为返回类型,则相同的代码也有效。但不是响应实体类。我做错了什么,如果我需要客户端也相同的响应实体

  • 我在尝试运行此程序时遇到以下异常。我正在使用在线编译器。甚至在读取字符串后尝试使用nextLine(),但没有成功。 我得到了以下异常:输入客户名称:在线程“main”java中输入客户id异常。util。NoSuchElementException:在java中找不到行。util。扫描仪。nextLine(Scanner.java:1585)位于Main。main(main.java:12)

  • 这个问题可能已经得到了回答,我读过很多类似的,但对我不起作用。因此,我的具有扩展的自定义表模型。我的数据是和列名。那么,当我的数据发生更改时,如何更新表呢?我一直在使用,它正在工作,但它将我的自定义单元格呈现器重置为默认值。谢了。