繁体   English   中英

Cassandra BoundStatement的线程安全

[英]Thread-safety of Cassandra BoundStatement

该文档指导如何使用Cassandra准备和绑定语句。

它说:

您应该只准备一次,然后将PreparedStatement缓存在应用程序中(它是线程安全的)。 ... BoundStatement不是线程安全的。 您可以使用不同的参数多次重复使用实例,但是只能在单个线程中使用同步调用:

BoundStatement bound = ps1.bind();

// This is safe:
bound.setString("sku", "324378");
session.execute(bound);

bound.setString("sku", "324379");
session.execute(bound);

// This is NOT SAFE. executeAsync runs concurrently with your code, so the first execution might actually read the
// values after the second setString call, and you would insert 324381 twice:
bound.setString("sku", "324380");
session.executeAsync(bound);

bound.setString("sku", "324381");
session.executeAsync(bound);

显然,上面的代码不是线程安全的,但是如果我们以这种方式更改代码,则:

BoundStatement bound1 = ps1.bind();
BoundStatement bound2 = ps1.bind();

bound1.setString("sku", "324380");
session.executeAsync(bound1);

bound2.setString("sku", "324381");
session.executeAsync(bound2);

即:对多个线程使用通用的PreparedStatement,每个线程使用其自己的BoundStatement。

1)此线程安全吗?

2)是否采用这种建议的方式与准备好的语句并行执行? 还是BoundStatements昂贵/创建缓慢/消耗大量内存等原因,以保持它们的数量少?

简短的答案是,如果您打算多次使用同一个PreparedStatement对象,但每次都使用不同的BoundStatement对象来限制参数,那么它是线程安全的,因为PreparedStatement是线程安全的,因此您可以在多个线程中重用它,而BoundStatement则不是线程安全的因此您每次都有不同的对象。

只是要清楚-因此,线程1将使用ps1 = session.prepare("insert into product (sku, description) values (?, ?)");创建prepare语句ps1 = session.prepare("insert into product (sku, description) values (?, ?)"); 其他所有线程将使用此ps1对象创建自己的BoundStatement对象,因为每个线程都有自己的要传递的值,例如:

线程1将绑定并执行为(注意,使用相同的ps1对象):

BoundStatement bound = ps1.bind().setString("sku", "001").setString("description", "LCD screen"); 
session.execute(bound);

线程2将绑定并执行为(注意,使用相同的ps1对象):

BoundStatement bound = ps1.bind().setString("sku", "002").setString("description", "TFT screen"); 
session.execute(bound);

线程3将绑定并执行为(注意,使用相同的ps1对象):

BoundStatement bound = ps1.bind().setString("sku", "003").setString("description", "LED screen"); 
session.execute(bound);

简而言之 :创建PreparedStatement对象时会产生主要的性能成本,因为它需要往返数据库服务器(请参见下面的描述),因此您可以重用该对象并且它是线程安全的,而每次创建一个单独的BoundStatement都是因为它是不是线程安全的,创建也不是繁重的事情,并且不要往返于DB服务器。

在此处输入图片说明

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM