jOOQ复杂更新-如何锁定表



这里是一个嵌套集模型的"add node" SQL查询

LOCK TABLE mytestdb.tbltree WRITE;
SELECT @myRight := rgt FROM mytestdb.tbltree
WHERE name = 'apples';
UPDATE mytestdb.tbltree SET rgt = rgt + 2 WHERE rgt > @myRight;
UPDATE mytestdb.tbltree SET lft = lft + 2 WHERE lft > @myRight;
INSERT INTO mytestdb.tbltree(name, lft, rgt) 
VALUES('beans', @myRight + 1, @myRight + 2);
UNLOCK TABLES;   

和映射到jOOQ

Record record = create.select(Tbltree.RGT)
    .from(Tbltree.TBLTREE)
    .where(Tbltree.NAME.equal("apples"))
    .fetchOne();
int myright = record.getValue(Tbltree.RGT);
create.update(Tbltree.TBLTREE).set(Tbltree.RGT, Tbltree.RGT.add(2))
      .where(Tbltree.RGT.greaterThan(myright)).execute();
create.update(Tbltree.TBLTREE).set(Tbltree.LFT, Tbltree.LFT.add(2))
      .where(Tbltree.LFT.greaterThan(myright)).execute();
TbltreeRecord record2 = (TbltreeRecord) create 
    .insertInto(Tbltree.TBLTREE, Tbltree.NAME, Tbltree.LFT, Tbltree.RGT)
    .values("cherries",myright+1,myright+2)
    .returning(Tbltree.ID)
    .fetchOne();

如何锁表?我应该吗?

thx

我不太确定你的各种查询在做什么,所以我不知道在你的情况下显式表锁定是否必要。但是我可以帮你学习语法。

从你的语法,我猜你使用MySQL作为底层数据库。您至少有三个选项可以将SQL转换为jOOQ:

  1. 使用MySQL的LOCK TABLES语句也在jOOQ:

    try {
      create.execute("LOCK TABLES mytestdb.tbltree WRITE");
      // [...] your jOOQ code
    }
    // Be sure to unlock your tables again, in case of failure!
    finally {
      create.execute("UNLOCK TABLES");
    }
    
  2. 使用FOR UPDATE子句,该子句也由SQL-1992规范指定(用于游标)。这个解决方案可能有点昂贵,因为MySQL实际上会为Result:

    准备一个游标。
    create.selectFrom(TBLTREE).forUpdate().execute();
    
  3. 扩展jOOQ并为LOCK TABLESUNLOCK TABLES语句创建自己的org.jooq.Query

最新更新