Laravel по-русски

Русское сообщество разработки на PHP-фреймворке Laravel.

Ты не вошёл. Вход тут.

#1 15.12.2017 01:16:41

htclog81
Откуда: Москва
Сообщений: 192
Сайт

Защита от повторных запросов БД или Redis

Всем привет!

Продолжаю работать над проектом с оплатой и подписками braintree.

Возник вопрос защиты от повторных запросов на подписку пользователя. Собственно если не блокировать кнопку submit их легко воспроизвести. А проверка в начале обработки запроса на то, что пользователь уже подписан, не помогает. Все потому что создание подписки состоит из двух частей запроса через API к шлюзу и добавление в БД. Запрос к Braintree может и пару секунд занять. И возникает race_conditions.

Насчет того что бы сначала создать подписку в БД в статусе "не связана с Braintree", затем обратиться к Braintree и обновить подписку в БД по результатам. Да так можно и тогда данной проблемы нет.. Но так по ряду причин не хочется.

Вопрос как лучше быть? В начале создания подписки залочить юзера на создание новых подписок через поле в БД в users или создать в Cache запись... Понятно дело что в конце запроса когда подписка уже сохранена в БД можно снять лок.  Как то бороться с помощью повторной отправки именно самой формы считаю смысла нет. Ну а если в разных табах для одного и того же юзера подписку добавляем таже ведь проблема..


Код создания подписки

	public function createSubscription($request)
	{	
		
		if (isset($request['payment_method_nonce'])) {
			$gatewayCustomer = $this->findOrCreateCustomer();
			$this -> createPaymentMethod($request['payment_method_nonce'], $gatewayCustomer);
		}
		
		$trial_ends_at = isset($request['trial_ends_at']) ? $request['trial_ends_at'] : null;
		
		$plan = Plan::findOrFail($request["plan_id"]);
		
		
		if (!empty($this->defaultCard)) {
			$gatewaySubscription =  $this -> createGatewaySubscription($plan, $trial_ends_at);
		} 
		
		$subscription = $this->subscriptions()->create([
			'plan_id' => $plan->id,
			'trial_ends_at' => $trial_ends_at,
			'gateway_id' => isset($gatewaySubscription) ? $gatewaySubscription -> id : null,
			'card_id' => isset($this->defaultCard) ? $this->defaultCard->id : null,
		]);
	}

Логика учитывает создание подписки и юзером и админом. И в том числе и с обращением и без к Braintree

Изменено htclog81 (15.12.2017 01:17:42)

Не в сети

#2 15.12.2017 11:33:00

Re: Защита от повторных запросов БД или Redis

https://laravel.ru/forum/viewtopic.php?id=3115 для вдохновения:)

Не в сети

#3 15.12.2017 12:04:59

htclog81
Откуда: Москва
Сообщений: 192
Сайт

Re: Защита от повторных запросов БД или Redis

Я читал это. Но там не до конца конкретно. Да проверять надо на бекенде... Лочить возможность  добавки пока первый запрос не прошел, отсекая повторные. Собственно про то как это лучше сделать я и спрашиваю.

Не в сети

Подвал раздела