Давайте представлю, что мы имеем некоторую хорошую, простую таблицу:Операторы Oracle MERGE, выполняемые в параллельных транзакциях: как предотвратить дублирование ключей?
CREATE TABLE blah (
some_key VARCHAR(32),
some_value VARCHAR(32)
);
По какой-то причине мы не хотим, чтобы определить первичный ключ или уникальный индекс на some_key
колонки.
Теперь мы выполняем в MERGE
отчетности в параллельных транзакциях (т.е. второго один запускаются перед первым совершенным):
MERGE INTO blah blah
USING (SELECT 'some_key' some_key, 'a_value' some_value FROM DUAL) rec
ON (blah.some_key = rec.some_key)
WHEN MATCHED THEN
UPDATE SET blah.some_value = rec.some_value
WHEN NOT MATCHED THEN
INSERT (blah.some_key, blah.some_value) VALUES (rec.some_key, rec.some_value);
и:
...
USING (SELECT 'some_key' some_key, 'another_value' some_value FROM DUAL) rec
...
После совершения одновременно SELECT
показывает следующие:
| SOME_KEY | SOME_VALUE |
|----------|---------------|
| some_key | a_value |
| some_key | another_value |
Я понимаю, e механика за этим (т. два оператора слияния не «видят» друг друга), но это как-то явно не желаемый результат.
Конечно, я могу определить ключ UNIQUE
. Затем происходит второй этап, что также объяснимо, но как-то неожиданно из заявления MERGE
.
Есть ли способ сделать MERGE
сделать «реальный» MERGE
без каких-либо дубликатов «ключей»?
No. в параллельный сценарий, вы не можете предотвратить дублирование 100% без каких-либо уникальных ограничений. Если вы не возражаете размещать блокировку на всей таблице в течение всей транзакции, которая (маловероятна). – sstan
Нет, замок на весь стол на самом деле не то, что я ищу ;-) –
Я так не думал :). Но я отправил ответ, который может быть вам полезен. – sstan