parser

Написать ответ на текущее сообщение

 

 
   команды управления поиском

Так делать нельзя...

Sumo 27.03.2015 12:15

Представим ситуацию, когда два пользователя одновременно пытаются зарегистрировать один и тот же логин:
— Проверили логин user для Пользователя 1. Свободно.
— Проверили логин user для Пользователя 2. Свободно.
— Добавили логин user для Пользователя 1.
— Добавили логин user для Пользователя 2... И огребли ошибку «запись с таким ключем уже есть».

В параллельных системах это называется «состояние гонки». Так делать не нужно.

Правильный способ:
— Делаем инсерт в базу данных нового пользователя.
— Если огребаем ошибку «запись с таким ключем уже есть», то говорим пользователю, что логин занят.

Пример функции из PF'а:
@userAdd[aOptions][k;v]
## Добавляет пользователя
## aOptions.login
## aOptions.password
## aOptions.isActive
## aOptions.<> - поля из _extraFields
## result[id пользователя] 
  $result[]
  ^cleanMethodArgument[]
  ^pfAssert:isTrue(def $aOptions.login)[Не задан login.]
  ^CSQL.safeInsert{
    ^CSQL.void{
      insert into $_usersTable (^_extraFields.foreach[k;v]{^if(^aOptions.contains[$k]){`^if(def $v){$v}{$k}`, }} login, password, is_active)
      values (^_extraFields.foreach[k;v]{^if(^aOptions.contains[$k]){"$aOptions.[$k]", }} "^taint[$aOptions.login]", "^taint[^passwordHash[$aOptions.password]]", "^aOptions.isActive.int(1)")
    }
    $result[^CSQL.lastInsertId[]]
  }{
     ^throw[pfAuth.user.exists;Пользователь "$aOptions.login" уже есть в системе.] 
   }