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是昂贵/缓慢创建/消耗大量内存等原因,以保持它们的数量低?
答案 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服务器。