зеркало из
				https://github.com/iharh/notes.git
				synced 2025-11-04 15: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.  
 | 
						|
Опять же, эта опция позволяет повысить конкурентность выполнения транзакций и избежать ненужных ожиданий на блокировках.
 | 
						|
*****************************************************************************************************
 |