【问题标题】:Cassandra Datastax saveQuery with Lightweight TransactionsCassandra Datastax saveQuery 与轻量级事务
【发布时间】:2015-09-26 04:39:02
【问题描述】:

我正在尝试通过 BatchStatement 将对象持久化到 cassandra

import com.datastax.driver.mapping.Mapper;

batch.add(mapper.saveQuery(itr.next()));

而且我想有 IF NOT EXISTS 子句像

INSERT INTO customer_account (customerID, customer_email) 
VALUES (‘LauraS’, ‘lauras@gmail.com’)
IF NOT EXISTS;

我应该如何通过 saveQuery 实现 IF NOT EXISTS?

【问题讨论】:

    标签: java cassandra


    【解决方案1】:

    不幸的是,映射 API 仅支持简单的 CRUD 操作,因此在这种情况下,轻量级事务是不可能的。您可以使用两种方法来解决此问题:

    1. 使用映射访问器,那么您的代码将如下所示 访问接口:

      @Accessor
      public interface UserAccessor {
          @Query("INSERT INTO sandbox.user (user_id, name) VALUES (:userId, :name) IF NOT EXISTS")
          Statement insertUser(@Param("userId") UUID userId, @Param("name") String name);
      }
      

      代码中的某处:

      Statement statement = userAccessor.insertUser(user.getUserId(), user.getName());
      

      然后你可以把声明放在BatchStatement

    2. 使用查询生成器:

      Insert insert = new QueryBuilder(cluster).insertInto("sundbox", "user")
              .value("user_id", user.getUserId())
              .value("name", user.getName())
              .ifNotExists();
      

      InsertStatement 的子类型,因此您也可以将它放在BatchStatement 中。注意,我用的是Driver 2.2.0,所以我用new QueryBuilder(cluster).insertInto(...,如果你用较低的驱动版本,你应该用QueryBuilder.insertInto(...

    【讨论】:

    • 当我在插入语句中使用 'ifNotExists()' 时,我看到错误“com.datastax.driver.core.exceptions.UnavailableException:没有足够的副本可用于在一致性 QUORUM 下查询(需要 2 个)但只有 1 个活着)”在删除 ''ifNotExists()'' 时不会出现。我正在使用 datastax 驱动程序 2.1.7。
    • 如果使用轻量级事务,则需要使用准确的副本因子。如果您只有一个节点,则将键空间的“replication_factor”更改为 1