All streams
Search
Write a publication
Pull to refresh
5
0

Программист

Send message

Бизнес логика не зависит от языка реализации. Вы не можете сделать сложение двух чисел разными способами, отличающимися от языка к языку.

Вот если мы будем говорить про криптографию, векторные операции - тогда да. Джава не подходит, потому что не умеет, но обычные if-else программы работают одинаково везде. Ветвление не удастся сделать как-то иначе, чем это позволяет оборудование.

Но, если мы говорим про общий случай, когда речь идет о произвольной программе из всего множества возможных, тогда да, я с вами согласен, но речь шла не про общий случай в статье =)

Банкомат работает с сервисом контрактов, а не с отдельными компонентами платежной системы.

Вы же, что бы получить деньги в банке (представляете, так можно, прийти в кассу и снять деньги) - не идете к инкасатору с документами вместо кассира, что бы он вам отсыпал денег?

Еще раз повторяю. ЦБ и банки - это анахронизм и его давно пора убирать. Те государства, которые это своевременно не поймут - уйдут в историю.
В mireapay ничего в номер счета не зашито и нет смысла этого делать.

Вы пытаетесь разговаривать со мной с точки зрения текущей инфраструктуры, которую автор и ставит своей целью упразднить и убрать.

И да, у меня есть способ, как мигрировать на новую инфраструктуру. Это не быстрый процесс, но реальный.

Счет - это совокупность балансов. У вас на счету может быть множество валют одновременно и при этом эти валюты сами могут быть типизированными, как ранее описывал.

Сервис контрактов следит за тем, что бы, если 100 рублей списали у Васи, то эти 100 рублей обязательно у кого-то оказались.
Контракт не завершится, если сальдо с бульбой не сойдется. У кого-то -100, у кого-то +100. Иначе никак. Причем с соблюдением типа.

Сервис Баланс сделан целенаправленно именно таким, что работает с конкретным счетом и говорит о том, что он конкретно может по запросу сделать.

Приведу пример развернуто из того, что было выше:

Что бы перевести 100 рублей от Васи к Пете - сервис контрактов в начале попытается создать платеж у Васи, когда сервис Баланс скажет, что создал списание на 100 обычных рублей под идентификатором запроса Списание1, то сервис контрактов отправит запрос за зачисление 100 рублей Пете (мы не можем сразу же формировать зачисление, потому что не знаем вектор типа перечисляемых Пете рублей, у Васи могут быть маркированные рубли же, причем сам Вася о том, что его рубли меченные никогда не узнает, в будущем будет статья про СОРМ). Если сервис Баланс опять сообщит, что зачислить могу и жду подтверждения по идентификатору Зачисление1, тогда контракт переходит в стадию "Завершение". В этой стадии он уже не может быть отменен никем, даже системой, и отправляются подтверждения созданных ранее Списание1 и Зачисление1. В этот момент Петя получает свои деньги, а Вася получить обратно свои деньги уже не сможет, потому что контракты не отменяются и удалить их нельзя.
Если он отправил деньги Пете по ошибке, то нужно создавать контракт на обратный перевод.

А теперь представь себе, что Вася живет в Москве, а Петя в Рио - о какой централизованной БД может идти речь?

Деньги в системе никуда не пропадают.
Сервис Баланс - это подсистема большой системы и сами валюты - это один из ресурсов, которыми оперирует подсистема контрактов.

Вся платежная система строилась исходя из того, что будут центры в каждой области, плотность расположения узлов - в соответствии с нуждами экономики. Нет никакой централизации в проведении платежей у системы и она не нужна.

Это работает только при условиях:
1. Система не распределенная;
2. Все балансы одинаковые.

В сервисе Баланс все сущности типа баланс на данный момент величины векторные, приведу пример, есть рублевый баланс, но на них есть метка "Не для перевода заграницу", так же у вас есть рублевый баланс без ограничений, запишем их как (рубль,["Не для перевода заграницу"]) и (рубль,[]) соответственно. Эти балансы разные и их нельзя смешивать, это как разные типы. При попытке снять средства для оплаты зарубежной покупки - рубли с первого баланса недоступны.

Так же нужно учитывать, что сервис Баланс списывает деньги вникуда и зачисляет деньги изниоткуда. Куда уйдут деньги - решает сервис контрактов. Поэтому так важно, что бы сервис Баланс сообщил точно, какой тип средств он списал. Потому что разница между (рубль,["Не для перевода заграницу"]) и (рубль,[]) существенна.

В будущем, эта фича может быть использована для локализации денег в определенном контуре экономики государства. Например выдается кредит, льготный, фермеру на покупку оборудования, гсм и семян и только у отечесвенного производителя. На эти деньги он ничего кроме этих категорий купить не может. Он даже положить их на депозит не сможет, потому что это тоже "покупка", просто покупаешь в этом случае долг с типом "депозит".
Когда эти деньги получит отечественный производитель, то он с ними идет "куда-то", где ему эти деньги меняют на что-то, что было обговорено заранее в рамках программы, все же такие вещи не делаются персонально под одного фермера.

В приведенном вами примере идет настолько существенное упрощение, что работать это будет только если есть некая центральная СУБД, куда все стекается, у каждого в ней есть счет и в итоге получаем ЦБ дубль 2. Не надо так.

Когда происходит создание платежа - средства резервируются. Они находятся на балансе, но другие процессы их получить не могут. Это то, как работает сервис Баланс сейчас и то, как он должен работать после выполнения домашнего задания.

Про бухгалтерскую терминологию ничего не знаю.

Если на пальцах:

У вас есть 1000 рублей. Если одновременно будет 11 списаний по 100 рублей, то 10 из них сообщат, что списать могут и ждут команду на подтверждение или отмену, и 11 скажет, что денег нет, но вы держитесь. Какой конкретно платеж будет одинадцатым - определить нельзя, любой из 11, при условии, что создавались одновременно.

Блокировки записей тут не происходит, блокируются значения, сами средства, поэтому и есть возможность не использовать транзакции БД или блокировку записей.

Сущность баланс всегда принадлежит конкретному пользователю, на нее не может быть 1000рпс, да и количество обращений значения не имеет на самом деле. Больше сказать не могу, т.к. хочу, что бы вы сделали самостоятельно домашнее задание.
Если что, мне ваш код не нужен - и сам напишу =)

Обработка платежа - это создать все необходимые записи, если их можно создать, ведь средств может не хватать, а затем завершить или отменить.


Смысл в том, что бы списать или начислить нужное количество средств и сохранить информацию о том, почему это было произведено. Транзакция описывает причину списания или зачисления. Это как пункт в чеке.

В рамках сервиса Баланс возможно агрегирование нескольких списаний с одной сущности баланс, а так же наоборот разделение списания между разными сущностями баланс, когда не хватает средств.

Приведу пример:

Вам нужно оплатить покупку билета в метро, скажем 50 рублей. Но у вас есть 20 рублей обычных и 30 рублей только для оплаты метро. В итоге ваше списание 50 рублей создаст 2 транзакции, хотя для вас это платеж один, продавец при этом получит ваши 20 обычных рублей и 30 специальных рублей, что он с ними будет делать - это отдельный разговор.

Пример 2:

Вы заказали пиццу (900р) и желаете сразу оплатить чаевые курьеру (100р), хотя система отправит 900р и 100р тем, кто их должен получить, с вашего баланса, на котором есть 1000 рублей, будет списано 1000 рублей и создано 2 транзакции, описывающие причину списания (одна на оплату пиццы, вторая на перевод чаевых).

(Это то, как сейчас работает сервис Баланс)

Запретить вам иметь свое мнение не могу, но пока хабр явно не запрещает подобное поведение, то не вижу причин не использовать такую возможность.
Если закроют, просто уйду на другую платформу, которая такую возможность поддерживает. Все просто. Так же как и для вас достаточно не читать статью =)
Желаю вам успехов!

Во-первых, проект все же делается и развивается. Во-вторых, есть фильтры, вы же можете не читать неинтересные вам статьи.

Впрочем видимо статьи о релокации и "как я трудоустроился в европе" вам больше подходят?

Обращение для работодателей не просто так убрано в спойлер. Что бы ее не читали те, кому это не нужно.

Воронка продаж. С точки зрения бизнеса нужно затянуть пользака. Идеальным вариантом будет дать ему собирать корзину без авторизации. Каждый дополнительный шаг будет только уменьшать конверсию.
Когда пользак соберет все что хотел - предложить зарегаться или авторизоваться.
Если откажется - в идеале все равно дать оформить заказ, дальше в любом случае будет звонок медежера по доставке и т.д. Полностью автоматизированная доставка только у крупных дистрибьюторов типа озона есть. А вот маленькому магазину, типа водовоза или всеинструменты - такое не особо и надо.

Тут только 2 варианта - БД и редис. Конечно есть третий, но пользователи вас возненавидят.

Для неавторизованных хранить в БД корзину - такое себе. Самое лучшее решение - когда нужна корзина - генерим айдюк большой и отдаем его пользаку в кукисы. У себя храним в редисе. Даже если пользак авторизуется потом - у него доступ к корзине остается. И главное что бек будет простой. + бесплатная фича в виде возможности создавать неск. корзин одному пользаку (тогда потребуется в приложении видеть кукис).
В саму корзину кладем только минимальные данные, т.е. айдюки и количества. Ну еще промо-коды, если успели применить. Не более.

Конечно можно в кукисы писать саму корзину, но тогда нужно будет каждый раз валидировать данные, присылаемые клиентом. Нагрузка на бэк будет куда как больше, чем кажется + увеличение траффика (привет любителям писать в кукисы 100500 мб данных) - все кукисы на каждый запрос отправляются. Учитывая то, как сейчас фронт по сотне запросов на бек отправляет, то к чему это приведет - очевидно.

Даже если будут спамить, то система защиты от ДДос обязана сработать. А так, корзина - это не более 100 элементов. Если у вас айдюки - это ууиды, то на каждый будет 36 байт ууид + 2 байта кавычки + 1 байт запятая, т.е. 3900 байт, округлим до 4 кб там еще будет доп мусор наверняка. Редис обычно все равно делается с запасом по памяти, т.е. стоит взять сразу невероятные 8 ГБ - получается, что ~2 097 152 заполненных корзин поместится в кеш. Я конечно не эксперт по безе, но кажется не заметить такое будет трудно, если начнут дудосить.
Для крупных торговых площадок, типа яндекса.маркет или озон такой подход не подойдет напрямую, нужно немного допиливать и усложнять, хотя основа такая же. Разница будет принципиальная только в том, что есть шардированние и гео-распределение серверов, с ними надо правильно работать. Пользак может "мигрировать" внезапно из одного региона в другой. В этом случае надо как-то понимать откуда брать его корзину (ну или забить на этих приключенцев). Но даже в этом случае я бы не стал хранить содержимое корзины в кукисах.

Редис - это не состояние, это особый вид БД, который способен хранить только ключ-значение. При этом данные, даже в случае нештатного отключения не теряются, т.к. есть лог-файл.

Разумеется.
Вопрос в том, что в сессии на конкретном сервере храняться данные, которые на других серверах являются недоступными. Именно это является состоянием.

Хранение состояния != кеширование.

Пример кеширования:
1. Твитты лежат в редисе, а не БД, если пользователь опять выполнит запрос.
2. Для проверки доступа нужно получить вектор доступа пользователя к ресурсу, его из БД каждый раз брать не надо.

Пример состояния:
1. У вас сессия хранит корзину. Добавляя туда что-то - вы на сервере в сессию пишете новые записи.
2. Мастер настройки "чего-то" из нескольких этапов. Каждый этап хранится в сессии, пока не дойдете до последнего шага.

Приношу свои извинения, изначально планировал статью на 2 академических часа, пришлось резать текст. Хабр не поддерживает сегментацию статей. Написанный объем текста уже приводит к паузам в 5-6 секунд при нажатии клавиш. Что-то править становится невозможно.

Это не проблема транзакций, а кривизна рук разработчиков.
Есть золотое правило - не отправлять в топики сообщения, когда у тебя активна транзакция. Все.
Если во время отправки упало - повтори все по новой, читай про идемпотентность

Проверил, работает. Образ меньше, 604 мб. Но у меня там еще кое-какие инструменты, которые в этой статье не отражены =)

в alpine нет apt вроде. А пакетный менеджер в любом случае много должен дать объема.
И большая часть из тех 900 мб - это ненужные бинарники и библиотеки пострги. Насколько мне известно стендэлон решения для pg_dump нет. Во всяком случае в виде образа.

Мне кажется, что решать надо не через pg_dump, а через PGDATA, но там свои проблемы.

try { 
    return readTraverseAndDoManyChecks(params);
} catch(NotFoundException ignored) {
    // no logging needed at DEBUG-ERROR levels
    return defaultValueIfNotFoundOrNotValid(params);
}

Вы предлагаете это все упаковать в Optional, что бы потом делать orElseGet.
А сам Optional будет получаться как куча проверок внутри метода readTraverseAndDoManyChecks с рекурсивными проверками, что вот тут-то мы уже получили то, что нужно и можно результат вернуть.
И не забывай, что исключение можно создать с отключенным стектрейсом. Скорость работы в этом случае вообще не страдает.

Не надо впадать в идеализм. Отказ от инструментов только потому, что тебе проповедник сказал, что так делать нельзя - идея плохая. Взвесь все за и против, и уже потом принимай решение. Это называется инженерный подход. Всякие правила имеют исключения и попытка закрывать на них глаза называется верой.

Оно действительно так, если у вас долгие транзакции и вы пытаетесь проводить какие-то сложные операции.
Если транзакция заканчивается сразу после этих изменений, то другие транзакции это увидят и будут выполнять свои запросы соответствующим образом. Не бывает так, что запрос начал выполняться с одними данными, а закончил с другими, тогда пример с вставкой и удалением не работал бы, а должен. Атомарность где?

Опять же, прошу в гитхаб и попробуй сломать пример. Покажи какую конфигурацию нужно сделать или манипуляции произвести, что бы тот код перестал работать (при условии, что после апдейта транзакция должна быть закрыта сразу). Нужно что бы счетчик параллельных блокировок хотя бы раз сообщил об ошибке.

Information

Rating
Does not participate
Location
Москва, Москва и Московская обл., Россия
Registered
Activity