Увеличение и получение значения счетчика

Есть ли способ увеличить счетчик, а затем вернуть значение за один вызов?

Или это единственный способ сделать 2 звонка?


person cool breeze    schedule 20.10.2016    source источник
comment
Вам нужно значение до приращения, после приращения или и до, и после?   -  person Eli Sadoff    schedule 20.10.2016
comment
@EliSadoff Мне нужно значение после приращения.   -  person cool breeze    schedule 20.10.2016
comment
Поскольку в scala нет оператора ++, вы должны увеличить счетчик, а затем вернуть значение.   -  person Eli Sadoff    schedule 20.10.2016


Ответы (1)


Это не фантомное ограничение, а ограничение Cassandra API, в CQL нет ничего, что позволяло бы вам получать и обновлять значение в одном и том же вызове API, и для этого есть очень и очень веская причина.

Когда вы обновляете значение счетчика, CQL выглядит следующим образом:

UPDATE keyspace.table SET counter = counter + 1 WHERE a = b;

Однако это маскирует истинную сложность распределенной блокировки, которую Cassandra должна пройти, чтобы выполнить, казалось бы, простое приращение. Это связано с тем, что очень сложно убедиться, что каждый счетчик обновляет значение latest и что несколько приращений одного и того же счетчика завершатся с одним и тем же значением.

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

Операция чтения проста:

SELECT * FROM keyspace.table WHERE a = b;

Если вы думаете, что экономите много времени с точки зрения сети или сложности, делая это, вы, вероятно, не экономите, если только объем операций чтения/записи не огромен. Короче говоря, мысль приятная, но я бы не стал заморачиваться.

for {
  inc <- database.table.update.where(_.a = b).modify(_.counter increment 1).future()
  value <- database.table.select(_.counter).where(_.a = b).one()
} yield value
person flavian    schedule 20.10.2016