Pull to refresh
6
0

Программист

Send message

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

Проверил, работает. Образ меньше, 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 с рекурсивными проверками, что вот тут-то мы уже получили то, что нужно и можно результат вернуть.
И не забывай, что исключение можно создать с отключенным стектрейсом. Скорость работы в этом случае вообще не страдает.

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

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

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

Речь в статье не просто про лок, а про контроль целостности.

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

Использовать редис или любой другой инструмент только потому, что хочется - не является инженерныv подходом, а любительством. Вам действительно нужен инструмент, который при падении теряет все ваши данные? Редис же в памяти работает. А ваша БД - она даже если упадет, целостность гарантирует.

Насколько мне известно, в MySQL есть 2 движка - myisam, innodb, какой именно вы использовали? Первый даже не поддерживает внешние ключи и по сути своей не подходит для серьезной работы. Иннодб получше и скорее всего там такой проблемы быть не должно.

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

поправил, так лучше?

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

250 очков гриффиндору!

Например используя рефлексию в Java можно вызвать метод класса А, передав ей инстанс класса Б, наследующего от А.
Опять же, в JS жесткие правила. Никакой магии нет. Ты либо знаешь как работают эти правила, либо для тебя это все какая-то авада кедавра. Не надо списывать собственную лень на неинтуитивность. Программирование и не должно быть интуитивным, таким языком никто не будет пользоваться. Это не интерфейс ворда или фотошопа.

А что с ним не так? Оно же идет по правилам. Причем сведено до если-то. Если лень прочесть спецификацию языка, то да, будет не понятно.

Для получения более заразного и опасного вируса - продлите прописку?

На паникующих легче заработать, можно любую дичь втирать.

Скоро хабр переименуют в твиттер и ограничат длинну статьи в 255 символов.

Ei incumbit probatio qui dicit, non qui negat

Использовать Page нежелательно, потому что это всегда 2 запроса к БД - 1 выбор данных, 2 подсчет числа доступных элементов. В вашем случае нет фильтров, но в если они будут, то можно легко повесить БД под нагрузкой таким образом.

Есть в спринге класс Slice - это тот же Page, но без вычисления количества страниц и элементов, желательно использовать именно его. Работать будет быстрее, а если нужно вычислять количество подходящих страниц и элементов, то фронту лучше делать 1 запрос в специальный эндпоинт для этого.

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

@NoRepositoryBean
public class JpaSpecificationRepositoryWithSliceImpl<T, ID extends Serializable>
        extends SimpleJpaRepository<T, ID>
        implements JpaSpecificationRepositoryWithSlice<T, ID> {
    private final EntityManager em;

    public JpaSpecificationRepositoryWithSliceImpl(JpaEntityInformation<T, ?> entityInformation, EntityManager em) {
        super(entityInformation, em);
        this.em = em;
    }

    @Transactional(readOnly = true)
    @Override
    public Slice<T> sliceAll(Specification<T> spec, Pageable pageable) {
        var list = this.getQuery(spec, pageable)
                .setFirstResult((int) pageable.getOffset())
                .setMaxResults(pageable.getPageSize())
                .getResultList();
        return new SliceImpl<>(list);
    }

    @Transactional(readOnly = true)
    @Override
    public Slice<T> sliceAll(Pageable pageable) {
        var cb = em.getCriteriaBuilder();
        var q = cb.createQuery(getDomainClass());
        var f = q.from(getDomainClass());
        q.select(f);
        q.orderBy(QueryUtils.toOrders(pageable.getSort(), f, cb));
        var list = em.createQuery(q)
                .setFirstResult((int) pageable.getOffset())
                .setMaxResults(pageable.getPageSize())
                .getResultList();
        return new SliceImpl<>(list);
    }
}

Разница между Page и Slice на 1 000 000 элементов даже без фильтров будет весьма ощутимой уже на глаз. В первом случае вся БД всегда читается, во втором только кусочек ограниченный размером страницы.

Information

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