Очень не хватает

языка программирования с транзакциями.

Что бы можно было для функции написать три «тела» — что делать в обычном случае, что делать в случае «отката» и что делать в случае «откат не удался». Приходится писать настолько феерически некрасиво и многословно, отрабатывая на каждом шагу каждый чих, что в результате основной алгоритм теряется в нагромождении if/case/try.

Впрочем, ерланговый подход «дай ему умереть» помогает с этим не то что бы справиться, но, по крайней мере, как-то упорядочить. Особенно если придерживаться еще одного правила — «молчи, если не спрашивают» (т.е. функция set(some, value) не должна ничего возвращать никогда).

Попутно задумался о применимости dz-товского фантома. Может я, конечно, чего-то не понимаю, но по моим ощущениям применимость идеи фантома ограничена случаем «нечто в себе с очень ограниченным взаимодействием со внешним миром». Ну т.е. настолько редкий и мизерный выигрыш от пресловутой persistence, что даже не смешно.

13 Comments

  1. avatar solom:

    Эт те лисп нужен с его макросами. Там это делается.
    PS разреши комментарии в ЖЖ, а?

    Ответить

    avatar

    Alex Ott отвечает на Август 7th, 2010 11:20:

    и такой лисп уже есть, называется Clojure

    Ответить

    avatar

    Fyodor Ustinov отвечает на Август 7th, 2010 13:17:

    Пример?

    P.S. Не разрешу

    Ответить

  2. Haskell — STM позволяет решить что делать при откате. В Clojure есть транзакции, но нет пока возможности указать что делать при откате — она просто перезапускается заново

    Ответить

    avatar

    Fyodor Ustinov отвечает на Август 7th, 2010 13:28:

    Если я правильно понял — STM это попытка решить ту проблему, которой в ерланге просто нет, за отсутствием переменных и разделяемой памяти.

    Ответить

    avatar

    Alex Ott отвечает на Август 7th, 2010 15:35:

    отсутствие разделяемой памяти это конечно хорошо, но больно многословно писать. плюс, как ты будешь координировать изменение сразу нескольких объектов?
    по умолчанию в кложуре объекты неизменяемые, они могут меняться только в определенном наборе объектов — ссылки (STM), агенты (асинхронное изменение), атомы и т.п.

    Ответить

    avatar

    Fyodor Ustinov отвечает на Август 7th, 2010 16:31:

    Это всё хорошо, пока нет взаимодействия с «внешним миром».
    Если мне нужно поменять значение переменной А, запись в базе Б и отправить пакет в порт Ц, то мне нужна не столько атомарность этой операции (понятно, что она недостижима), но хотя-бы возможность средствами языка описать что делать если на любом из этих этапов произошёл сбой. Понятно что я и сейчас могу это описать, только запись типа

    try put_to_base(data) of
    ok ->
    try put_to_file(data) of
    ok ->
    try put_to_screen(data) of
    ok -> ok;
    error -> throw(error)
    catch
    _:_ -> throw(error)
    end;
    error -> throw(error)
    catch
    _:_ -> undo_put_to_file(), throw(error)
    end;
    error -> throw(error)
    catch
    _:_ -> undo_put_to_base(), throw(error)
    end.

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

    try
    {ok, base} = {put_to_base(data), base},
    {ok, file} = {put_to_file(data), file},
    {ok, screen} = {put_to_screen(data), screen},
    ok
    catch
    _:{badmatch, {_, What}} ->
    case What of
    file -> undo_put_to_file(), undo_put_to_base();
    base-> undo_put_to_base()
    end
    end.

    Но это тоже не лучший вариант.

    Ответить

    avatar

    Alex Ott отвечает на Август 7th, 2010 18:37:

    ну сейчас народ в Clojure думает на тему сопряжения STM с прочими транзакционными системами, в принципе наверное можно попробовать сопрячь механизмы, чтобы оно вело лог действий, и в разных точках выполнения использовало разные rollback процедуры

    Ответить

  3. avatar dimas:

    Э-э-э, объекты, экспепшены и финалли?

    Ответить

    avatar

    Fyodor Ustinov отвечает на Август 9th, 2010 18:40:

    Я там сверху пример привел. Изобрази?

    Ответить

    avatar

    dimas отвечает на Август 9th, 2010 19:11:

    а в чем проблема то?

    ну, БД откатывается элементарно — транзакция делается отдельным объектом, по вылету за область видимости автоматом откатывается.

    для переменной — ну да, нужно делать какую-то обертку, как и для записи в файл … но, как вариант, надо смотреть шо вообще делается, а то вдруг можно заредизайнить :)

    «серебряной пули нет» (с)

    p.s. я, кстати, когда писал свою первую фиговину для явы, жутко бесился что фиг его знает когда деструктор вызовут, поэтому приходится больше руками писать …

    Ответить

    avatar

    Fyodor Ustinov отвечает на Август 9th, 2010 19:16:

    Дим, я не говорю что это сделать нельзя.
    Я говорю, что меня напрягает писать все эти обёртки вручную. Хочется аутоматичности.

    Ответить

    avatar

    dimas отвечает на Август 9th, 2010 19:21:

    я был в иллюзии что такое будет еще лет десять назад :)

    правда, ожидал что и оверхед на это все будет еще хуже :)

    Ответить

Leave a Reply