vault backup: 2024-06-19 20:13:52
This commit is contained in:
parent
c4c3431957
commit
b0f3b8e995
24
.obsidian/plugins/home-tab/data.json
vendored
24
.obsidian/plugins/home-tab/data.json
vendored
@ -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": [],
|
||||||
|
@ -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
24
_inbox/Repeatable read.md
Normal 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
13
_inbox/Serializable.md
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
aliases:
|
||||||
|
tags:
|
||||||
|
- зрелость/🌱
|
||||||
|
date:
|
||||||
|
- - 2024-06-19
|
||||||
|
zero-link:
|
||||||
|
- "[[00 Базы Данных]]"
|
||||||
|
parents:
|
||||||
|
- "[[Уровни изоляций транзакций БД]]"
|
||||||
|
linked:
|
||||||
|
---
|
||||||
|
**Serializable (упорядочиваемость).** Самый высокий уровень изолированности; транзакции полностью изолируются друг от друга, каждая выполняется так, как будто параллельных транзакций не существует. Только на этом уровне параллельные транзакции не подвержены эффекту «фантомного чтения». ^fdb385
|
@ -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. Таким образом, вторая транзакция повлияла на выполнение первой.
|
@ -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)
|
@ -16,6 +16,6 @@ linked:
|
|||||||
|
|
||||||
![](Read%20committed.md#^11df20)
|
![](Read%20committed.md#^11df20)
|
||||||
|
|
||||||
**Repeatable read (повторяющееся чтение).** Уровень, при котором читающая транзакция «не видит» изменения данных, которые были ею ранее прочитаны. При этом никакая другая транзакция не может изменять данные, читаемые текущей транзакцией, пока та не окончена.
|
![](Repeatable%20read.md#^38dd4b)
|
||||||
|
|
||||||
**Serializable (упорядочиваемость).** Самый высокий уровень изолированности; транзакции полностью изолируются друг от друга, каждая выполняется так, как будто параллельных транзакций не существует. Только на этом уровне параллельные транзакции не подвержены эффекту «фантомного чтения».
|
![](Serializable.md#^fdb385)
|
||||||
|
BIN
meta/files/Pasted image 20240619201135.png
Normal file
BIN
meta/files/Pasted image 20240619201135.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 901 KiB |
BIN
meta/files/Pasted image 20240619201149.png
Normal file
BIN
meta/files/Pasted image 20240619201149.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 768 KiB |
Loading…
Reference in New Issue
Block a user