зеркало из
				https://github.com/iharh/notes.git
				synced 2025-10-31 13:46:08 +02:00 
			
		
		
		
	
		
			
				
	
	
		
			26 строки
		
	
	
		
			3.4 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			26 строки
		
	
	
		
			3.4 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| *****************************************************************************************************
 | |
| В PostgreSQL есть мощный механизм блокировок, который как раз может помочь избежать таких ситуаций на уровне базы данных, упростив разработку приложения.
 | |
| 
 | |
| Выражение SELECT FOR UPDATE, в отличии от обычного SELECT устанавливает блокировку на уровне строк (row-level lock), что и позволяет безопасно поменять данные, 
 | |
| избежав конфликтных ситуаций. Когда мы используем SELECT FOR UPDATE, блокировка не дает изменить или удалить выбранные строки другим транзакциям, до завершения текущей транзакции.
 | |
| 
 | |
| Если продолжать аналогию с системой бронирования номеров в отеле, то можно привести вот такой пример запроса:
 | |
| 
 | |
| BEGIN ;
 | |
| 
 | |
| SELECT * FROM rooms WHERE room._number = '10' and status = 'available' FOR UPDATE;
 | |
| 
 | |
| Здесь мы явно открываем транзакцию (BEGIN) и из таблицы с номерами отеля (rooms) , выбираем комнату с номером 10 и статусом свободна (available).
 | |
| 
 | |
| Таким образом мы можем быть уверены, что пока пользователь выбирает и оплачивает номер, другой не успеет его забронировать, так как запись будет заблокирована до конца транзакции.
 | |
| 
 | |
| Чтобы избежать ситуаций когда SELECT FOR UPDATE не может получить блокировку, так как строка заблокирована другой транзакцией, 
 | |
| в результате чего происходят сильные задержки в транзакции или взаимоблокировки, существует опция NOWAIT. 
 | |
| Эта опция позволяет приложению избежать конфликтов блокировок в реальном времени, вместо того чтобы ждать когда освободиться необходимая строка.
 | |
| 
 | |
| Существует еще одна полезная опция в контексте выражения SELECT FOR UPDATE, называется она SKIP LOCKED. 
 | |
| Суть ее состоит в том, что она позволяет избежать строк, которые уже заблокированы другой транзакцией. 
 | |
| Т.е. в примере, приведенном выше, если бы вторая транзакция искала свободные номера, то она бы не увидела в своем результате комнату с номером 10.  
 | |
| Опять же, эта опция позволяет повысить конкурентность выполнения транзакций и избежать ненужных ожиданий на блокировках.
 | |
| *****************************************************************************************************
 | 
