我相信我發現瞭如何在Cassandra csharp驅動程序(2.7.3版)中的StatementFactory中緩存預準備語句的邏輯。這是用例。在Cassandra Csharp驅動程序中準備好的語句緩存問題
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
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語句。在我們的例子中,我們在不同的密鑰空間(又名會話)中有相同的表名。我們在兩個查詢中的cql語句看起來都是一樣的。即DELETE FROM foo_bar WHERE id =?。
如果我不得不猜測,我會說一個簡單的解決辦法是將cql語句和keyspace結合在一起作爲緩存鍵。
有沒有其他人遇到過這個問題?