vault backup: 2024-06-19 20:13:52

This commit is contained in:
Struchkov Mark 2024-06-19 20:13:52 +03:00
parent c4c3431957
commit b0f3b8e995
No known key found for this signature in database
GPG Key ID: A3F0AC3F0FA52F3C
9 changed files with 87 additions and 35 deletions

View File

@ -23,25 +23,25 @@
"markdownOnly": false, "markdownOnly": false,
"unresolvedLinks": false, "unresolvedLinks": false,
"recentFilesStore": [ "recentFilesStore": [
{
"filepath": "_inbox/Неповторяющееся чтение.md",
"timestamp": 1718817191076
},
{ {
"filepath": "knowledge/dev/database/Уровни изоляций транзакций БД.md", "filepath": "knowledge/dev/database/Уровни изоляций транзакций БД.md",
"timestamp": 1718816928649 "timestamp": 1718817183091
},
{
"filepath": "_inbox/Транзакция БД.md",
"timestamp": 1718816827388
},
{
"filepath": "knowledge/dev/database/Проблемы при параллельном выполнении нескольких транзакций.md",
"timestamp": 1718816823586
}, },
{ {
"filepath": "_inbox/Потерянное обновление.md", "filepath": "_inbox/Потерянное обновление.md",
"timestamp": 1718816800840 "timestamp": 1718817154181
}, },
{ {
"filepath": "_inbox/Race condition.md", "filepath": "_inbox/Repeatable read.md",
"timestamp": 1718816771915 "timestamp": 1718817107184
},
{
"filepath": "_inbox/Serializable.md",
"timestamp": 1718817019589
} }
], ],
"bookmarkedFileStore": [], "bookmarkedFileStore": [],

View File

@ -1,9 +1,25 @@
{ {
"recentFiles": [ "recentFiles": [
{
"basename": "Неповторяющееся чтение",
"path": "_inbox/Неповторяющееся чтение.md"
},
{ {
"basename": "Уровни изоляций транзакций БД", "basename": "Уровни изоляций транзакций БД",
"path": "knowledge/dev/database/Уровни изоляций транзакций БД.md" "path": "knowledge/dev/database/Уровни изоляций транзакций БД.md"
}, },
{
"basename": "Потерянное обновление",
"path": "_inbox/Потерянное обновление.md"
},
{
"basename": "Repeatable read",
"path": "_inbox/Repeatable read.md"
},
{
"basename": "Serializable",
"path": "_inbox/Serializable.md"
},
{ {
"basename": "Транзакция БД", "basename": "Транзакция БД",
"path": "_inbox/Транзакция БД.md" "path": "_inbox/Транзакция БД.md"
@ -12,10 +28,6 @@
"basename": "Проблемы при параллельном выполнении нескольких транзакций", "basename": "Проблемы при параллельном выполнении нескольких транзакций",
"path": "knowledge/dev/database/Проблемы при параллельном выполнении нескольких транзакций.md" "path": "knowledge/dev/database/Проблемы при параллельном выполнении нескольких транзакций.md"
}, },
{
"basename": "Потерянное обновление",
"path": "_inbox/Потерянное обновление.md"
},
{ {
"basename": "Race condition", "basename": "Race condition",
"path": "_inbox/Race condition.md" "path": "_inbox/Race condition.md"
@ -24,10 +36,6 @@
"basename": "Безмастерная репликация", "basename": "Безмастерная репликация",
"path": "_inbox/Безмастерная репликация.md" "path": "_inbox/Безмастерная репликация.md"
}, },
{
"basename": "Неповторяющееся чтение",
"path": "_inbox/Неповторяющееся чтение.md"
},
{ {
"basename": "Фантомное чтение", "basename": "Фантомное чтение",
"path": "_inbox/Фантомное чтение.md" "path": "_inbox/Фантомное чтение.md"
@ -191,14 +199,6 @@
{ {
"basename": "Вопросы работодателю", "basename": "Вопросы работодателю",
"path": "notes/Собеседования/Вопросы работодателю.md" "path": "notes/Собеседования/Вопросы работодателю.md"
},
{
"basename": "Улучшение производительности отдельного сервиса",
"path": "_inbox/Улучшение производительности отдельного сервиса.md"
},
{
"basename": "Блокирующие вызовы",
"path": "knowledge/dev/Блокирующие вызовы.md"
} }
], ],
"omittedPaths": [], "omittedPaths": [],

24
_inbox/Repeatable read.md Normal file
View File

@ -0,0 +1,24 @@
---
aliases:
- повторяющееся чтение
tags:
- зрелость/🌱
date:
- - 2024-06-19
zero-link:
- "[[00 Базы Данных]]"
parents:
- "[[Уровни изоляций транзакций БД]]"
linked:
---
**Repeatable read (повторяющееся чтение).** Уровень, при котором читающая транзакция «не видит» изменения данных, которые были ею ранее прочитаны. При этом никакая другая транзакция не может изменять данные, читаемые текущей транзакцией, пока та не окончена. ^38dd4b
![](Pasted%20image%2020240619201149.png)
Первая транзакция началась. Считала баланс первого пользователя. Обновила его, но не зафиксировала изменения. Началась вторая транзакция. Она также считала баланс первого пользователя, обновила его, но тоже не зафиксировала свои изменения.
А теперь правильной окажется та транзакция, которая зафиксирует свои изменения первой. Первая транзакция выполнила коммит первой, поэтому коммит второй транзакции завершился ошибкой.
Но если вторая транзакция не изменяла данные, а добавляла новые строчки, то исключения не было бы. Также проблем не будет, если мы обновим баланс второго пользователя.
Но возникает закономерный вопрос: что делать с ошибкой, ведь мы хотели выполнить транзакцию, которая свалилась с исключением. Самое простое, что можно сделать — это повторить выполнение второй транзакции с новыми данными. Если исключение возникнет опять, то повторить снова.

13
_inbox/Serializable.md Normal file
View File

@ -0,0 +1,13 @@
---
aliases:
tags:
- зрелость/🌱
date:
- - 2024-06-19
zero-link:
- "[[00 Базы Данных]]"
parents:
- "[[Уровни изоляций транзакций БД]]"
linked:
---
**Serializable (упорядочиваемость).** Самый высокий уровень изолированности; транзакции полностью изолируются друг от друга, каждая выполняется так, как будто параллельных транзакций не существует. Только на этом уровне параллельные транзакции не подвержены эффекту «фантомного чтения». ^fdb385

View File

@ -10,5 +10,14 @@ zero-link:
parents: parents:
- "[[Проблемы при параллельном выполнении нескольких транзакций]]" - "[[Проблемы при параллельном выполнении нескольких транзакций]]"
linked: linked:
link: https://struchkov.dev/blog/ru/transactional-isolation-levels/#%D0%BD%D0%B5%D0%BF%D0%BE%D0%B2%D1%82%D0%BE%D1%80%D1%8F%D1%8E%D1%89%D0%B5%D0%B5%D1%81%D1%8F-%D1%87%D1%82%D0%B5%D0%BD%D0%B8%D0%B5
--- ---
**Неповторяющееся чтение (non-repeatable reads).** Запрос с одними и теми же условиями даёт неодинаковые результаты в рамках транзакции. ^3e8781 **Неповторяющееся чтение (non-repeatable reads).** Запрос с одними и теми же условиями даёт неодинаковые результаты в рамках транзакции. ^3e8781
Эта проблема присутствует на уровне изоляции [Read committed](Read%20committed.md) и [Read uncommitted](Read%20uncommitted.md).
Рассмотрим пример. Начинаем первую транзакцию. Считываем баланс пользователя, получаем значение 1000. Далее стартует вторая транзакция в отдельном потоке, а текущий поток засыпает.
Во второй транзакции устанавливаем пользователю баланс равный 100_000. После чего закрываем вторую транзакцию. Баланс успешно обновился в БД.
Первая транзакция продолжает выполнение. Снова запрашивает баланс пользователя из БД, на этот раз получает значение 100_000. Таким образом, вторая транзакция повлияла на выполнение первой.

View File

@ -10,6 +10,7 @@ zero-link:
parents: parents:
- "[[Проблемы при параллельном выполнении нескольких транзакций]]" - "[[Проблемы при параллельном выполнении нескольких транзакций]]"
linked: linked:
link: https://struchkov.dev/blog/ru/transactional-isolation-levels/#%D0%BF%D0%BE%D1%82%D0%B5%D1%80%D1%8F%D0%BD%D0%BD%D0%BE%D0%B5-%D0%BE%D0%B1%D0%BD%D0%BE%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5
--- ---
**Потерянное обновление (lost update).** Две параллельные транзакции меняют одни и те же данные, при этом итоговый результат обновления предсказать невозможно. ^23d01d **Потерянное обновление (lost update).** Две параллельные транзакции меняют одни и те же данные, при этом итоговый результат обновления предсказать невозможно. ^23d01d
@ -86,6 +87,11 @@ public class LostUpdateExample {
Вторая транзакция прибавляет к балансу пользователя 5 (31-34). После чего вторая транзакция также закрывается (38, 39). Баланс пользователя в БД равен 1005. Мы потеряли обновления, которые выполнила первая транзакция. Такое поведение называют [Race condition](Race%20condition.md). Вторая транзакция прибавляет к балансу пользователя 5 (31-34). После чего вторая транзакция также закрывается (38, 39). Баланс пользователя в БД равен 1005. Мы потеряли обновления, которые выполнила первая транзакция. Такое поведение называют [Race condition](Race%20condition.md).
Изменим уровень транзакций на более изолированный. В примере у нас используется `READ_COMMITTED`, установим  в строке 45. Изменим уровень транзакций на более изолированный. В примере у нас используется `READ_COMMITTED`, установим [Repeatable read](Repeatable%20read.md) в строке 45.
В таком случае при выполнении нашего кода получаем исключение `PSQLException`. В таком случае при выполнении нашего кода получаем исключение `PSQLException`.
![](Pasted%20image%2020240619201135.png)
## Дополнительные материалы
- [Пример на Java](https://github.com/Example-uPagge/transactional/blob/master/jdbc-transaction/src/main/java/dev/struchkov/example/transaction/problems/LostUpdateExample.java)

View File

@ -16,6 +16,6 @@ linked:
![](Read%20committed.md#^11df20) ![](Read%20committed.md#^11df20)
**Repeatable read (повторяющееся чтение).** Уровень, при котором читающая транзакция «не видит» изменения данных, которые были ею ранее прочитаны. При этом никакая другая транзакция не может изменять данные, читаемые текущей транзакцией, пока та не окончена. ![](Repeatable%20read.md#^38dd4b)
**Serializable (упорядочиваемость).** Самый высокий уровень изолированности; транзакции полностью изолируются друг от друга, каждая выполняется так, как будто параллельных транзакций не существует. Только на этом уровне параллельные транзакции не подвержены эффекту «фантомного чтения». ![](Serializable.md#^fdb385)

Binary file not shown.

After

Width:  |  Height:  |  Size: 901 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 768 KiB