在卡桑德拉Csharp的司机准备的语句缓存问题 [英] Prepared statement caching issue in Cassandra Csharp driver

查看:484
本文介绍了在卡桑德拉Csharp的司机准备的语句缓存问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我相信我已经找到了如何准备语句在StatementFactory在卡桑德拉CSHARP驱动程序(版本2.7.3)缓存的逻辑错误。这里是用例

I believe I have found a bug with the logic of how a prepared statement is cached in the StatementFactory in the Cassandra csharp driver (version 2.7.3). Here is the use case.

Guid key = Guid.NewGuid(); // your key

ISession session_foo = new Session("foo"); //This is pseudo code
ISession session_bar = new Session("bar");

var foo_mapper = new Mapper(session_foo); //table foo_bar
var bar_mapper = new Mapper(session_bar); //table foo_bar

await Task.WhenAll(
   foo_mapper.DeleteAsync<Foo>("WHERE id = ?", key),
   bar_mapper.DeleteAsync<Bar>("WHERE id = ?", key));

我们已经发现,运行此删除后,只有第一个请求成功。在 StatementFactory的源代码后跳水

We have found that after running this deletes, only the first request is succeeding. After diving in the the source code of StatementFactory

public Task<Statement> GetStatementAsync(ISession session, Cql cql)
    {
        if (cql.QueryOptions.NoPrepare)
        {
            // Use a SimpleStatement if we're not supposed to prepare
            Statement statement = new SimpleStatement(cql.Statement, cql.Arguments);
            SetStatementProperties(statement, cql);
            return TaskHelper.ToTask(statement);
        }
        return _statementCache
            .GetOrAdd(cql.Statement, session.PrepareAsync)
            .Continue(t =>
            {
                if (_statementCache.Count > MaxPreparedStatementsThreshold)
                {
                    Logger.Warning(String.Format("The prepared statement cache contains {0} queries. Use parameter markers for queries. You can configure this warning threshold using MappingConfiguration.SetMaxStatementPreparedThreshold() method.", _statementCache.Count));
                }
                Statement boundStatement = t.Result.Bind(cql.Arguments);
                SetStatementProperties(boundStatement, cql);
                return boundStatement;
            });
    }

您可以看到缓存只使用CQL声明。在我们的例子中,我们在不同的keyspaces(又名会话)相同的表名。我们在这两个查询CQL声明看起来是一样的。即 DELETE FROM foo_bar这样WHERE ID =?

You can see that the cache only uses the cql statement. In our case, we have the same table names in different keyspaces (aka sessions). Our cql statement in both queries look the same. ie DELETE FROM foo_bar WHERE id =?.

如果我猜的话,我会说,一个简单的解决将是对CQL结合声明和密钥空间一起作为缓存键。

If I had to guess, I would say that a simple fix would be to combine the cql statement and keyspace together as the cache key.

有没有其他人遇到这个问题之前?

Has anyone else run into this issue before?

推荐答案

作为一个简单的解决办法,我使用DoNotPrepare跳过缓存

As a simple workaround, I am skipping the cache by using the DoNotPrepare

await _mapper.DeleteAsync<Foo>(Cql.New("WHERE id = ?", key).WithOptions(opt => opt.DoNotPrepare()));



我也发现的 Datastax

这篇关于在卡桑德拉Csharp的司机准备的语句缓存问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆