У нас есть таблица MQT (TESTMQT), которая выбирает данные из таблицы TEST1. У нас также есть индекс по MQT, поэтому наша программа может использовать собственный ввод-вывод по MQT. У нас также есть триггер «Перед обновлением» на MQT, поэтому вместо непосредственного обновления MQT обновляется таблица TEST1 (в случае, если программе объявлено MQT в F-spe c).
Проблема в том, что даже если это триггер скомпилирован с commit = * none и программа SQLRPGLE также скомпилирована с commit = * none, по какой-то причине данные, обновленные в таблице TEST1, обновляются в цикле фиксации 5, но MQT обновляется в цикле фиксации 0 (я вижу это в журнале) , Я ожидал, что, поскольку программа была скомпилирована с Commit = * none, все транзакции НЕ будут выполняться при фиксации.
Не уверен, что это имеет значение, но эта программа, которая обновляет таблицу / mqt, вызывается из программы CL, которая запускает управление фиксацией с помощью scope (job) и lcklvl (* chg)
STRCMTCTL LCKLVL (* CHG ) CMTSCOPE (* JOB)
Итак, программа CL запускает обязательство по заданию и вызывает программу SQLRPGLE, которая компилируется с commit = * none. После завершения программы CL фиксирует изменения программы и завершает управление фиксацией.
В мониторе производительности я вижу, что перед запуском триггера уровень изоляции изменяется на UNCOMMITED READ с помощью SET TRANSACTION, но я не делаю этого явно в код. Я читал в IBM RedBook, что если триггер был создан с уровнем изоляции, отличным от вызывающего, уровень изоляции будет изменен, чтобы соответствовать уровню изоляции вызывающего. Я думал, что в моем случае Caller - это SQLRPGLE, который был скомпилирован с commit = * none, так как обновление в TEST1 выполняется при коммите? Из-за уровня изоляции uncommited чтения из SET TRANSACTION? Как проверить уровень изоляции вызывающего абонента?
Код MQT:
CREATE TABLE TESTLIB.TESTMQT ( TESTCODE, TESTDESC ) AS
(SELECT DECIMAL(CODE, 5), DESC
FROM TESTLIB.TESTTABLE)
DATA INITIALLY IMMEDIATE
REFRESH DEFERRED
ENABLE QUERY OPTIMIZATION
MAINTAINED BY USER
RCDFMT TESTMQT ;
CREATE UNIQUE INDEX TESTLIB.TESTIDX
ON TESTLIB.TESTMQT (TESTCODE);
Перед кодом триггера:
CREATE OR REPLACE TRIGGER TESTLIB.TESTTRGUP
NO CASCADE BEFORE Update On TESTLIB.TESTMQT
REFERENCING OLD As vOld
NEW As vNew
For Each Row Mode DB2ROW
SET OPTION COMMIT=*NONE
BEGIN ATOMIC
UPDATE TESTLIB.TESTTABLE
SET
CODE = vNew.TESTCODE,
DESC = vNew.TESTDESC
WHERE
CODE = vOld.TESTCODE;
END;