Use exclusive lock for view maintenance caused by UPDATE or DELETE (#42)
When using DELETE or UPDATE, we must use exclusive lock for now because apply_old_delta(_with_count) could result in wrong results with concurrent transactions. We would like to improve it in future, but we prevent it by using the lock for now.
This commit is contained in:
parent
26f0b03b58
commit
5db54f4669
2 changed files with 13 additions and 1 deletions
|
|
@ -237,7 +237,7 @@ When a base table is truncated, the IMMV is also truncated and the contents beco
|
|||
|
||||
### Concurrent Transactions
|
||||
|
||||
Suppose an IMMV is defined on two base tables and each table was modified in different a concurrent transaction simultaneously. In the transaction which was committed first, the IMMV can be updated considering only the change which happened in this transaction. On the other hand, in order to update the IMMV correctly in the transaction which was committed later, we need to know the changes occurred in both transactions. For this reason, `ExclusiveLock` is held on an IMMV immediately after a base table is modified in `READ COMMITTED` mode to make sure that the IMMV is updated in the latter transaction after the former transaction is committed. In `REPEATABLE READ` or `SERIALIZABLE` mode, an error is raised immediately if lock acquisition fails because any changes which occurred in other transactions are not be visible in these modes and IMMV cannot be updated correctly in such situations. However, as an exception if the IMMV has only one base table and doesn't use DISTINCT or GROUP BY, the lock held on the IMMV is `RowExclusiveLock`.
|
||||
Suppose an IMMV is defined on two base tables and each table was modified in different a concurrent transaction simultaneously. In the transaction which was committed first, the IMMV can be updated considering only the change which happened in this transaction. On the other hand, in order to update the IMMV correctly in the transaction which was committed later, we need to know the changes occurred in both transactions. For this reason, `ExclusiveLock` is held on an IMMV immediately after a base table is modified in `READ COMMITTED` mode to make sure that the IMMV is updated in the latter transaction after the former transaction is committed. In `REPEATABLE READ` or `SERIALIZABLE` mode, an error is raised immediately if lock acquisition fails because any changes which occurred in other transactions are not be visible in these modes and IMMV cannot be updated correctly in such situations. However, as an exception if the IMMV has only one base table and doesn't use DISTINCT or GROUP BY, and the table is modified by `INSERT`, then the lock held on the IMMV is `RowExclusiveLock`.
|
||||
|
||||
### Row Level Security
|
||||
|
||||
|
|
|
|||
12
createas.c
12
createas.c
|
|
@ -635,6 +635,18 @@ CreateIvmTrigger(Oid relOid, Oid viewOid, int16 type, int16 timing, bool ex_lock
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX: When using DELETE or UPDATE, we must use exclusive lock for now
|
||||
* because apply_old_delta(_with_count) doesn't work in concurrent situations.
|
||||
*
|
||||
* If the view doesn't have aggregate, distinct, or tuple duplicate, then it
|
||||
* would work. However, we don't have any way to guarantee the view has a unique
|
||||
* key before opening the IMMV at the maintenance time because users may drop
|
||||
* the unique index. We need something to resolve the issue!!
|
||||
*/
|
||||
if (type == TRIGGER_TYPE_DELETE || type == TRIGGER_TYPE_UPDATE)
|
||||
ex_lock = true;
|
||||
|
||||
ivm_trigger->funcname =
|
||||
(timing == TRIGGER_TYPE_BEFORE ? SystemFuncName("IVM_immediate_before") : SystemFuncName("IVM_immediate_maintenance"));
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue