Serializable блокує (насправді робить снепшот) не кожен читаємий рядок, а таблицю в цілому, якщо не помиляюсь. Рядок блокує якраз repeatable read. Таким чином serializable пофіг на додані рядки, а для repeatable read це новий рядок, тому він буде відображатись.
Точніше, не всю таблицю, а обраний діапазон, але все одно, воно правильніше сказати, що воно блокує не рядки, а робить снепшот і дивиться тільки в нього під час транзакції.
Вітаю! Дякую за комент, довелось освіжити знання) Згідно документації, таки блокує: "This level is like REPEATABLE READ, but InnoDB implicitly converts all plain SELECT statements to SELECT ... FOR SHARE if autocommit is disabled. If autocommit is enabled, the SELECT is its own transaction. It therefore is known to be read only and can be serialized if performed as a consistent (nonlocking) read and need not block for other transactions. (To force a plain SELECT to block if other transactions have modified the selected rows, disable autocommit.)" dev.mysql.com/doc/refman/8.0/en/innodb-transaction-isolation-levels.html тобто конвертує всі SELECT в SELECT ... FOR SHARE. Що і є блокуванням (SELECT FOR SHARE Sets a shared mode lock on any rows that are read. Other sessions can read the rows, but cannot modify them until your transaction commits.) можете скинути посилання на доку де йде мова про "снепшот"? Дякую
@@10xdev правильно зрозумів, що якщо в Transaction 1 with serializable isolation lvl: SELECT * FROM table WHERE a > 30 AND a < 50; і в паралельній Transaction 2: INSERT INTO table (a) VALUES (40); 2 тразакція буде блокнута до поки 1 не буде закомічена?
гарне питання, довелось перевіряти Коротка відповідь - так. Обширніша - там є певні оптимізації, і якщо обмежувати запит ідентифікатором (where id < 50), то вставка не блокується
@@10xdev хмм, цікаво. Я просто зараз тільки вивчаю db. Думав, що від подібних ситуацій якраз і придумана mvcc. Типу на 2 транзакцію створиться окрема версія page в таблиці і запишеться туди і, відповідно, новіша версія стане актуальною. Але для транзакції 1 буде заюзана попередня версія page. Стосовно snapshot є інфа в докі postgres: When a transaction is on the serializable level, a SELECT query sees only data committed before the transaction began and never sees either uncommitted data or changes committed during transaction execution by concurrent transactions. (However, the SELECT does see the effects of previous updates executed within this same transaction, even though they are not yet committed.) This is different from Read Committed in that the SELECT sees a snapshot as of the start of the transaction, not as of the start of the current query within the transaction. (www.postgresql.org/docs/7.1/xact-serializable.html)
Дуже доступно і просто пояснюєте, дякую велике!
Безцінний канал. Добре розʼяснення, дякую
Корисно. Дякую
Великий лайк
Так а что с добавлением колонки в большой базе данных? )
А в чому питання? У відео кажу що без блокування можна через тулзу pt-schema-change
Serializable блокує (насправді робить снепшот) не кожен читаємий рядок, а таблицю в цілому, якщо не помиляюсь. Рядок блокує якраз repeatable read. Таким чином serializable пофіг на додані рядки, а для repeatable read це новий рядок, тому він буде відображатись.
Точніше, не всю таблицю, а обраний діапазон, але все одно, воно правильніше сказати, що воно блокує не рядки, а робить снепшот і дивиться тільки в нього під час транзакції.
Вітаю!
Дякую за комент, довелось освіжити знання)
Згідно документації, таки блокує:
"This level is like REPEATABLE READ, but InnoDB implicitly converts all plain SELECT statements to SELECT ... FOR SHARE if autocommit is disabled. If autocommit is enabled, the SELECT is its own transaction. It therefore is known to be read only and can be serialized if performed as a consistent (nonlocking) read and need not block for other transactions. (To force a plain SELECT to block if other transactions have modified the selected rows, disable autocommit.)"
dev.mysql.com/doc/refman/8.0/en/innodb-transaction-isolation-levels.html
тобто конвертує всі SELECT в SELECT ... FOR SHARE. Що і є блокуванням (SELECT FOR SHARE Sets a shared mode lock on any rows that are read. Other sessions can read the rows, but cannot modify them until your transaction commits.)
можете скинути посилання на доку де йде мова про "снепшот"? Дякую
@@10xdev правильно зрозумів, що якщо в Transaction 1 with serializable isolation lvl: SELECT * FROM table WHERE a > 30 AND a < 50; і в паралельній Transaction 2: INSERT INTO table (a) VALUES (40); 2 тразакція буде блокнута до поки 1 не буде закомічена?
гарне питання, довелось перевіряти
Коротка відповідь - так.
Обширніша - там є певні оптимізації, і якщо обмежувати запит ідентифікатором (where id < 50), то вставка не блокується
@@10xdev хмм, цікаво. Я просто зараз тільки вивчаю db. Думав, що від подібних ситуацій якраз і придумана mvcc. Типу на 2 транзакцію створиться окрема версія page в таблиці і запишеться туди і, відповідно, новіша версія стане актуальною. Але для транзакції 1 буде заюзана попередня версія page.
Стосовно snapshot є інфа в докі postgres: When a transaction is on the serializable level, a SELECT query sees only data committed before the transaction began and never sees either uncommitted data or changes committed during transaction execution by concurrent transactions. (However, the SELECT does see the effects of previous updates executed within this same transaction, even though they are not yet committed.) This is different from Read Committed in that the SELECT sees a snapshot as of the start of the transaction, not as of the start of the current query within the transaction. (www.postgresql.org/docs/7.1/xact-serializable.html)