Рассмотрим две таблицы, подобные этой:
TABLE: current
-------------------
| id | dept | value |
|----|------|-------|
| 4| A | 20 |
| 5| B | 15 |
| 6| A | 25 |
-------------------
TABLE: history
-------------------
| id | dept | value |
|----|------|-------|
| 1| A | 10 |
| 2| C | 10 |
| 3| B | 20 |
-------------------
Это всего лишь простые примеры... в реальной системе обе таблицы имеют значительно больше столбцов и значительно больше строк (более 10 тыс. строк в текущей и более 1 млн строк в истории).
Клиентское приложение непрерывно (несколько раз в секунду) вставляет новые строки в текущую таблицу и «перемещает» более старые существующие строки из текущей в историю (удаление/вставка в рамках одной транзакции).
Не блокируя клиента в этом действии, нам нужно получить согласованную сумму значений для каждого отдела в двух таблицах.
С уровнем изоляции транзакций, установленным на REPEATABLE READ, мы могли бы просто сделать:
SELECT dept, sum(value) FROM current GROUP BY dept;
с последующим
SELECT dept, sum(value) FROM history GROUP BY dept;
и сложите два набора результатов вместе. НО каждый запрос будет блокировать вставки в соответствующую таблицу.
Изменение уровня изоляции на READ COMMITTED и выполнение тех же двух SQL-запросов позволит избежать блокировки вставок, но теперь существует риск двойного учета записей при перемещении из текущего в историю во время запроса (поскольку каждый SELECT создает свой собственный снимок).
Тогда вот вопрос... что происходит с уровнем изоляции READ COMMITTED, если я делаю UNION:
SELECT dept, sum(value) FROM current GROUP BY dept
UNION ALL
SELECT dept, sum(value) FROM history GROUP BY dept;
Будет ли MySQL генерировать непротиворечивый снимок обеих таблиц одновременно (тем самым устраняя риск двойного подсчета) или он по-прежнему сначала сделает снимок одной таблицы, а через некоторое время сделает снимок второй?