Валидация уникальности значения

hell0w0rd

Продвинутый новичок
// и конечно среди них будут правила валидации типа not_exists и unique
Я вот никогда не понимал таких валидаций. Это же база сама вам скажет при вставке, зачем делать проверку? Учитывая то, что между проверкой и вставкой может условие поменяться.
 
Последнее редактирование модератором:

grigori

( ͡° ͜ʖ ͡°)
Команда форума
"Это же база сама вам скажет при вставке", - отличный способ отстрелить себе ногу из-за race condition, особенно актуально при разделении запросов между серверами с лагами репликации.
Уникальность обеспечивается блокировками, и никак иначе. Autoincrement - это тоже блокировка.
Ты просто никогда не дебажил race condition и сегфолты по stack overflow :)
 
Последнее редактирование:

hell0w0rd

Продвинутый новичок
Погоди, ну вот у нас два параллельных запроса:
Код:
insert into users (username, password) values ('nkt', '...')
У нас на уровне базы разве не решится race condition, если в транзакцию завернуть?
На сколько я понимаю они выстроятся в очередь и 1 отработает, второй упадет с ошибкой об уникальности username, которую мы поймаем в приложении и отдадим bad request. Не?
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
@hell0w0rd, у нас два параллельных запроса:
insert into transaction_history(transaction_id, account_from,account_to,amount)
они выстроятся в очередь и 1 отработает, второй упадет с ошибкой об уникальности transaction_id, и тебя уволят за потерю денег клиента

это офтоп, предлагаю уйти в другую тему
 

hell0w0rd

Продвинутый новичок
@hell0w0rd, у нас два параллельных запроса:
insert into transaction_history(transaction_id, account_from,account_to,amount)
они выстроятся в очередь и 1 отработает, второй упадет с ошибкой об уникальности transaction_id, и тебя уволят за потерю денег клиента

это офтоп, предлагаю уйти в другую тему
Вынесешь, или мне создать? (тут по моим подсчетам 2-3 оффтопа точно есть, минимум)
Почему transaction_id высылает приложение в данном случае? И почему клиент деньги должен потерять?
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
@hell0w0rd, транзакция - сущность внешняя по отношению к базе. Обрабатываем уведомление из robokassa или paypal, они могут по несколько раз присылать уведомления о транзакциях, иногда с разными статусами.
База его получает от приложения потому что так по логике.
 

hell0w0rd

Продвинутый новичок
@hell0w0rd, транзакция - сущность внешняя по отношению к базе. Обрабатываем уведомление из robokassa или paypal, они могут по несколько раз присылать уведомления о транзакциях, иногда с разными статусами.
База его получает от приложения потому что так по логике.
ясно. То есть теперь мы перешли к распределенным транзакциям?
Я говорил исключительно про замкнутую систему, где есть база, есть клиент. Клиент шлет запрос на изменение данных и сервер никуда кроме своей базы не ходит.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
любой сайт с платежами - это распределенная система
 

Redjik

Джедай-мастер
Я вот никогда не понимал таких валидаций. Это же база сама вам скажет при вставке, зачем делать проверку? Учитывая то, что между проверкой и вставкой может условие поменяться.
потому что DDD, если бизнес логика основана на уникальном значении, то это должно быть в модели, все просто
 

fixxxer

К.О.
Партнер клуба
потому что DDD, если бизнес логика основана на уникальном значении, то это должно быть в модели, все просто
Может, не в модели, а на уровне domain layer?

Как ты проверишь уникальность на уровне модели? В контракте предусмотреть исключение или методы - понятно, так и надо. А реализацию как?
 

AnrDaemon

Продвинутый новичок
@hell0w0rd, транзакция - сущность внешняя по отношению к базе. Обрабатываем уведомление из robokassa или paypal, они могут по несколько раз присылать уведомления о транзакциях, иногда с разными статусами.
База его получает от приложения потому что так по логике.
Если транзакция внешняя, у неё должен быть твой собственный внутренний ID. Потом, при разборе лога, ты уже сможешь проследить, какая транзакция дважды записалась, ну и т.д. Бизнес-логика обязана отрабатывать возможность двойной регистрации внешней транзакции, ибо это нормально, у транзакции есть ИД, по которому можно отследить, какая из записей действительно актуальна.
Но записаны должны быть все.
 

hell0w0rd

Продвинутый новичок
потому что DDD, если бизнес логика основана на уникальном значении, то это должно быть в модели, все просто
Да какое DDD.
Вот был контроллер:
Код:
const validator = this.validate(req.body, {
  some_files: 'unique'
});
if (!validator.isValid()) {...}

const entity = this.service.createEntity(req.body);
Мой изначальный вопрос - зачем проверять уникальность, а потом создавать сущность, когда при создании мы можем получить ошибку о нарушении этой самой уникальности. Все. Не больше, не меньше.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
Бизнес-логика обязана отрабатывать возможность двойной регистрации внешней транзакции, ибо это нормально, у транзакции есть ИД, по которому можно отследить, какая из записей действительно актуальна.
Но записаны должны быть все.
Не так. Бизнес-логика подразумевает автоматический учет событий в realtime без разбора логов, но с выполнением действий - передачей заказа на склад для отгрузки.
Чей ID - неважно, в Robocassа мы сами его генерим. Нет актуальных или устаревших записей - есть события.
Если деньги зачислены - повторно зачислять их нельзя. Для этого нужна проверка факта обработки события. Запись о том, что событие отработано, должна быть уникальна. Дальше эта транзакция может быть отменена, это новое событие, но не дважды зачислены и не дважды списаны.
На время обработки события запись о транзакции блокируется.

Магазины, которые этого не делают, рассылают бесплатные планшеты и прочие ништяки.
Недавно на крупном женском форуме девки собирались по скайпу, человек по 10, и одновременно вводили себе код одного купона на 6pm, тарились шмотками.
 
Последнее редактирование:

Redjik

Джедай-мастер
Может, не в модели, а на уровне domain layer?

Как ты проверишь уникальность на уровне модели? В контракте предусмотреть исключение или методы - понятно, так и надо. А реализацию как?
да, конечно это имел ввиду
 

Sufir

Я не волшебник, я только учусь
А domain layer разве не является моделью предметной области выраженной в коде?
 

Вурдалак

Продвинутый новичок
А domain layer разве не является моделью предметной области выраженной в коде?
Под моделью понимается как отдельно взятый объект типа User, так и весь domain layer в целом. Очевидно, в этом контексте имелось в виду первое.
 

Redjik

Джедай-мастер
если на уровне домена подразумевается уникальное значение, значит логика должна быть в домене
что не так?
 
Сверху