Cassandra BoundStatement的线程安全性

时间:2017-04-26 10:25:37

标签: java multithreading cassandra thread-safety prepared-statement

This doc guides how to use Cassandra prepared and bound statements.

它说:

  

您应该只准备一次,并将PreparedStatement缓存到您的   应用程序(它是线程安全的)。 ... BoundStatement不是   线程安全的。您可以使用不同的方法多次重复使用实例   参数,但仅限于单个线程,并且仅在您使用时   同步电话:

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

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

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

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

{{1}}

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

1)这个线程安全吗?

2)这是否建议使用预处理语句并行执行?或者BoundStatements是昂贵/缓慢创建/消耗大量内存等原因,以保持它们的数量低?

1 个答案:

答案 0 :(得分:2)

简短的回答是,如果您打算多次使用相同的PreparedStatement对象,但每次使用不同的BoundStatement对象使用不同的参数,那么它是线程安全的,因为PreparedStatement是线程安全,所以你可以重复使用多个线程,BoundStatement不是线程安全的,所以你每次都有不同的对象。

只是要清楚 - 所以,你的线程1将使用ps1 = session.prepare("insert into product (sku, description) values (?, ?)");创建你的prepare语句,所有其他线程将使用这个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服务器。

enter image description here