cancel
Showing results for 
Search instead for 
Did you mean: 

Should SELECT forUpdate throw exception when exec in own transactional context and can't get a lock?

gregorw
Active Contributor
0 Kudos

Hello CAP Team,

I've the following after UPDATE handler for Books:

  srv.after("UPDATE", Books, async (req) => {
    const db = await cds.connect.to("db");
    const { Books: dbBooks } = db.entities;

    console.log("After request update triggered");
    await cds.tx(async (tx) => {
      const data = {
        title: "haha",
        stock: 0,
      };
      // Expectation: Throws an error if entity can not be locked because it was updated in the standard handler
      let exists = await SELECT(1).from(dbBooks, 11).forUpdate();
      console.log("before updating book in separate tx");
      const result = await tx.update(dbBooks, 11).with(data);
      console.log("after updating book in separate tx");
    });
  });<br>

When I run the following request:

###
PUT http://localhost:4004/admin/Books(11)
Authorization: Basic admin:
Content-Type: application/json

{
    "title": "test",
    "stock":12
}
the execution gets stuck in the line with the SELECT for Update.

I would expect that the SELECT forUpdate should throw an exception when it can't get a lock. What do you think?

If you want to replicate this issue please check bookshop-demo. The code is in srv/admin-service.js#L185 and the REST Client test request in tests/app/admin.http#L116.

Best Regards
Gregor

martinstenzig
Contributor
0 Kudos

Are you running into this problem on SQLite and HANA or just against a local SQLite?

gregorw
Active Contributor
0 Kudos

It occurs in SQLite and HANA.

gregorw
Active Contributor
0 Kudos

johannesvogel could you try to get someone who can help us here.

Accepted Solutions (0)

Answers (1)

Answers (1)

johannesvogel
Advisor
Advisor
0 Kudos

Hi Gregor,

if not wait time is specified, the default of the database applies (see https://cap.cloud.sap/docs/node.js/cds-ql#forupdate). On SAP HANA, that's the lock_wait_timeout of the index server.

let exists = await SELECT(1).from(dbBooks, 11).forUpdate({wait: 2});

This would wait for 2 seconds until it throws an error.

Best,

gregorw
Active Contributor
0 Kudos

Just a reference also to the .forUpdate() documentation.