簡體   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