Облегченная транзакция Cassandra в пакетном обновлении, влияющая на несколько разделов/таблиц

Существует сценарий, в котором мне нужно обновить несколько разделов (одной или другой таблицы) вместе. Рассмотрим пример заказов здесь:

create table test.orders_by_id(
    order_email text,
    order_id        timeuuid,
    order_name  text,
    order_status    int,                
    order_note  text,           //1 - Pending, 2 - In Progress, 3 - On Hold, 4 - Confirmed, 5 - Cancelled
    order_number text,
    PRIMARY KEY (order_id)
);

create table test.orders_by_number(
    order_email text,
    order_id    text,
    order_name  text,
    order_status    int,                
    order_note  text,
    order_number text,
    PRIMARY KEY (order_number)
);

create table test.work_audit_orders (
    order_id    text,
    log_id  timeuuid,
    log_audit text,
    PRIMARY KEY(order_id,work_log_id));

Вставка Таким образом, в приведенном выше случае добавление нового заказа потребует от меня использования пакета, поскольку это повлияет на таблицы orders_* и work_* и должно происходить одновременно. Это то, что можно сделать в пакетном режиме.

begin batch
        insert into test.orders_by_id(order_email,order_id,order_name,order_status,order_number) values ('[email protected]',d1918050-d310-11e6-946e-d368aab1da02,'ORDER_1023',1,'1235');
        insert into test.orders_by_number(order_email,order_id,order_name,order_status,order_number) values ('[email protected]','d1918050-d310-11e6-946e-d368aab1da02','ORDER_1023',1,'1235');
        insert into test.work_audit_orders(order_id,log_id,log_audit) values ('d1918050-d310-11e6-946e-d368aab1da02',now(),'New Order Created: order 1235');
apply batch;

Проблема с условным обновлением: Однако давайте рассмотрим случай, когда необходимо сравнить и установить, и на основе этого нам нужно изменить таблицу orders_*, а также таблицы work_*. Например, в зависимости от потока заказ может быть отменен только в состоянии ожидания. Здесь операторы обновления потребуют LWT, чтобы сделать его полностью сериализованным и избежать любых условий гонки. однако, как я понимаю, если мы обновим это в пакете, который должен быть связан только с одним разделом, поскольку реализация Paxos работает с детализацией раздела, следовательно, делая пакет ориентированным на условие, что затрудняет размещение всех операторов в та же партия:

begin batch
        update orders_by_id set order_status = 5 where order_id = d1918050-d310-11e6-946e-d368aab1da02 if order_status = 1;
        update orders_by_number set order_status = 5 where order_number='1235' if order_status = 1;
        insert into work_audit_orders (order_id, log_id, log_audit) values ('d1918050-d310-11e6-946e-d368aab1da02', now(),'Order 1235 Cancelled');
        apply batch;

Отчасти я считаю, что материализованные представления могут решить проблему с order_* и пакетом, но как мне позаботиться об операторах work_*, которые должны отражаться в пакете, чтобы гарантировать, что он правильно зарегистрирован и выполнен при отправке.

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


person Piyush    schedule 05.01.2017    source источник


Ответы (1)


LWT не может охватывать несколько разделов (следовательно, несколько таблиц), поэтому вам не повезло.

Мне кажется, что это аналогичный случай этого вопроса SO: Cassandra - Слишком большая партия. Взгляните на этот мой ответ и проверьте, подходит ли он для вашего варианта использования.

person xmas79    schedule 05.01.2017
comment
Я считаю, что использование одной таблицы определенно помогает, поскольку она изолирует и одновременно выполняет атомарные операции. Мне было интересно, есть ли на это простой ответ, похожий на mysql :( - person Piyush; 05.01.2017