简体   繁体   English

ORACLE SQL - 锁定表直到任务完成 [使用 EF Core]

[英]ORACLE SQL - Lock a table until a task finishes [Using EF Core]

I have a table called TOKEN .我有一个名为TOKEN的表。 TOKEN just contains 1 row with specific informations about an external web service. TOKEN仅包含 1 行,其中包含有关外部 web 服务的特定信息。 On the (possible multiple) client side I want to update the row in TOKEN (1x per week).在(可能多个)客户端,我想更新TOKEN中的行(每周 1 次)。 This happens by calling another web services etc. In that time nobody should be able to read and write to table TOKEN .这是通过调用另一个 web 服务等来实现的。在那个时候,没有人应该能够读取和写入表TOKEN Eg.例如。

  1. Lock TOKEN so no one can read and write锁定TOKEN ,这样就没人可以读写了
  2. Generate new informations by calling a web service (could go up to a few seconds) - client side!通过调用 web 服务生成新信息(go 可能需要几秒钟)- 客户端!
  3. update the row in TOKEN更新TOKEN中的行
  4. Unlock the table again and let the other read and write (although write would not be needed for the next week anymore).再次解锁表并让另一个读写(尽管下周不再需要写入)。

How could I achieve such a behaviour?我怎样才能实现这种行为? If 2 users try to execute the new info.如果 2 个用户尝试执行新信息。 generation at the same time (while the other one is already and still executing point 2.), corrupted data could be the result.同时生成(而另一个已经并且仍在执行第 2 点),结果可能是损坏的数据。 Any ideas?有任何想法吗?

As far as I can tell, in Oracle you can't block readers from reading the table.据我所知,在 Oracle 中,您无法阻止读者阅读表格。 Why wouldn't they be able to read "old" value, because it is valid until you "calculate" the new value?为什么他们不能读取“旧”值,因为它在您“计算”新值之前一直有效? I don't know how to prevent them to do so.我不知道如何阻止他们这样做。 Truncate the table (so that it is empty)?截断表(使其为空)?


Anyway: one option is to无论如何:一种选择是

  • use a function (because you want to return new value to caller)...使用 function (因为您想将新值返回给调用者)...
  • ... which is an autonomous transaction (otherwise you can't perform DML within)... ...这是一个自治事务(否则您无法在其中执行 DML)...
  • ... that uses ...使用
    • SELECT... FOR UPDATE to lock row for updates by other users SELECT... FOR UPDATE锁定行以供其他用户更新
    • LOCK in case table is empty; LOCK以防表为空; you might not need it because you already have some data in the table你可能不需要它,因为你已经在表中有一些数据

Here's a sample function;这是一个示例 function; see if it helps.看看是否有帮助。

FUNCTION f_token (par_id IN NUMBER)
   RETURN NUMBER
IS
   PRAGMA AUTONOMOUS_TRANSACTION;
   l_dummy  VARCHAR2 (1);
   l_token  NUMBER := 1;                 -- suppose default token value is "1"
BEGIN
       -- FOR UPDATE will "lock" row for updates by other users
       SELECT 'x'
         INTO l_dummy
         FROM token b
        WHERE b.id = par_id
   FOR UPDATE OF b.token;

   -- here you'd call another web services etc. and acquire new value into L_TOKEN

   UPDATE token b
      SET b.token = l_token
    WHERE b.id = par_id;

   COMMIT;                                         -- commit releases the lock
   RETURN (l_token);
EXCEPTION
   WHEN NO_DATA_FOUND
   THEN
      -- in case table is empty, lock it so that nobody can do anything with it, except you
      LOCK TABLE token IN EXCLUSIVE MODE;

      INSERT INTO token (id, token)
           VALUES (par_id, l_token);

      COMMIT;                                      -- commit releases the lock
      RETURN (l_token);
END f_token;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM