【问题标题】:How will i know that record was duplicate or it was inserted successfully?我如何知道该记录是重复的还是已成功插入?
【发布时间】:2015-10-02 03:12:25
【问题描述】:

这是我的 CQL 表:

CREATE TABLE user_login (
    userName varchar PRIMARY KEY,
    userId uuid,
    fullName varchar,
    password text,
    blocked boolean
);

我有这个datastax java驱动代码

PreparedStatement prepareStmt= instances.getCqlSession().prepare("INSERT INTO "+ AppConstants.KEYSPACE+".user_info(userId, userName, fullName, bizzCateg, userType, blocked) VALUES(?, ?, ?, ?, ?, ?);");

batch.add(prepareStmt.bind(userId, userData.getEmail(), userData.getName(), userData.getBizzCategory(), userData.getUserType(), false));


PreparedStatement pstmtUserLogin = instances.getCqlSession().prepare("INSERT INTO "+ AppConstants.KEYSPACE+".user_login(userName, userId, fullName, password, blocked) VALUES(?, ?, ?, ?, ?) IF NOT EXIST");

batch.add(pstmtUserLogin.bind(userData.getEmail(), userId, userData.getName(), passwordEncoder.encode(userData.getPwd()), false));
            instances.getCqlSession().executeAsync(batch);

这里的问题是,如果我删除 IF NOT EXIST 一切正常,但如果把它放回去,它就不会在表中插入记录也不会抛出任何错误。

那么我怎么知道我插入了重复的userName

我使用的是 cassandra 2.0.1

【问题讨论】:

    标签: cassandra cql datastax datastax-java-driver


    【解决方案1】:

    使用INSERT... IF NOT EXISTS,则可以使用ResultSet#wasApplied()查看结果:

    ResultSet rs = session.execute("insert into user (name) values ('foo') if not exists");
    System.out.println(rs.wasApplied());
    

    注意事项:

    • 此 CQL 查询是一个轻量级事务,具有性能影响。请参阅this article 了解更多信息。
    • 您的示例只有一个语句,您不需要批处理

    【讨论】:

    • 我有多个语句,这就是我使用批处理的原因。为简单起见,我只展示一个陈述
    • 在我原来的问题中,我做了这个更改instances.getCqlSession().execute(batch).wasApplied(),我得到了com.datastax.driver.core.exceptions.UnavailableException: Not enough replica available for query at consistency QUORUM (2 required but only 1 alive)我在我的本地系统上运行这个应用程序
    • 在这种情况下您不应使用批处理语句(请参阅the DataStax documentation)。这无论如何都不适用于条件更新,除非它们适用于相同的分区键(请参阅this other article)。
    • 你的意思是批处理不应该应用于两个不同的表?在我的场景中可能的解决方案是什么?
    • 关于您的一致性错误,请检查您的键空间上的replication_factor。如果你只有一个节点,它应该是 1。这里它似乎是 3(因为 quorum 是 2)。
    【解决方案2】:

    看起来您需要一个 ACID 事务,而 Cassandra,简单地说,不是 ACID。您绝对不能保证在您检查用户名是否存在的时间间隔内,它不会由其他人创建。 除此之外,在 CQL 标准中 INSERT 和 UPDATE 做同样的事情。他们都写了一个“新”记录,标记旧记录被删除。是否有旧记录并不重要。 如果您想即时验证或创建新用户,我想您可以使用复合键用户名 + 密码,并将您的查询作为更新,其中用户名 = 数据和密码 = 数据。 这样,如果用户给你一个错误的密码,你的查询就会失败。 如果用户是新用户,他不能提供“错误”密码,因此他的帐户被创建。 您现在可以测试您仅在第一次登录后设置的“已订阅”之类的字段,因此如果“刚刚创建”的用户将丢失

    【讨论】:

      猜你喜欢
      • 2013-10-03
      • 1970-01-01
      • 2010-12-12
      • 2021-07-06
      • 2023-02-10
      • 1970-01-01
      相关资源
      最近更新 更多