當前位置:首頁 > IT技術(shù) > Web編程 > 正文

Atomic Upsert | apache phoenix
2021-09-24 14:35:47

To support atomic upsert, an optional ON DUPLICATE KEY clause, similar to the MySQL syntax, has been encorporated into the UPSERT VALUES command as of Phoenix 4.9. The general syntax is described here. This feature provides a superset of the HBase Increment and CheckAndPut functionality to enable atomic upserts. On the server-side, when the commit is processed, the row being updated will be locked while the current column values are read and the ON DUPLICATE KEY clause is executed. Given that the row must be locked and read when the ON DUPLICATE KEY clause is used, there will be a performance penalty (much like there is for an HBase Put versus a CheckAndPut).

In the presence of the ON DUPLICATE KEY clause, if the row already exists, the VALUES specified will be ignored and instead either:

  • the row will not be updated if ON DUPLICATE KEY IGNORE is specified or
  • the row will be updated (under lock) by executing the expressions following the ON DUPLICATE KEY UPDATE clause.

Multiple UPSERT statements for the same row in the same commit batch will be processed in the order of their execution. Thus the same result will be produced when auto commit is on or off.

Examples

For example, to atomically increment two counter columns, you would execute the following command:

UPSERT INTO my_table(id, counter1, counter2) VALUES ('abc', 0, 0)
ON DUPLICATE KEY UPDATE counter1 = counter1 + 1, counter2 = counter2 + 1;

To only update a column if it doesn’t yet exist:

UPSERT INTO my_table(id, my_col) VALUES ('abc', 100)
ON DUPLICATE KEY IGNORE;

Note that arbitrarily complex expressions may be used in this new clause:

UPSERT INTO my_table(id, total_deal_size, deal_size) VALUES ('abc', 0, 100)
ON DUPLICATE KEY UPDATE
    total_deal_size = total_deal_size + deal_size,
    approval_reqd = CASE WHEN total_deal_size < 100 THEN 'NONE'
    WHEN total_deal_size < 1000 THEN 'MANAGER APPROVAL'
    ELSE 'VP APPROVAL' END;

Limitations

The following limitations are enforced for the ON DUPLICATE KEY clause usage:

  • Primary key columns may not be updated, since this would essentially be creating a new row.
  • Transactional tables may not use this clause as atomic upserts are already possible through exception handling when a conflict occurs.
  • Immutable tables may not use this clause as by definition there should be no updates to existing rows
  • The CURRENT_SCN property may not be set on connection when this clause is used as HBase does not handle atomicity unless the latest value is being updated.
  • The same column should not be updated more than once in the same statement.
  • No aggregation or references to sequences are allowed within the clause.
  • Global indexes on columns being atomically updated are not supported, as potentially a separate RPC across the wire would be made while the row is under lock to maintain the secondary index.
?

為了支持原子更新插入,從 Phoenix 4.9 開始,類似于 MySQL 語法的可選 ON DUPLICATE KEY 子句已合并到 UPSERT VALUES 命令中。此處描述一般語法。此功能提供了 HBase Increment 和 CheckAndPut 功能的超集,以啟用原子更新插入。在服務(wù)器端,當處理提交時,正在更新的行將被鎖定,同時讀取當前列值并執(zhí)行 ON DUPLICATE KEY 子句。鑒于在使用 ON DUPLICATE KEY 子句時必須鎖定和讀取該行,將會有性能損失(很像 HBase Put 與 CheckAndPut 的情況)。

在存在 ON DUPLICATE KEY 子句的情況下,如果該行已經(jīng)存在,則指定的 VALUES 將被忽略,而是:

  • 如果指定了 ON DUPLICATE KEY IGNORE 或
  • 該行將通過執(zhí)行 ON DUPLICATE KEY UPDATE 子句之后的表達式來更新(鎖定)。

同一提交批次中同一行的多個 UPSERT 語句將按照它們的執(zhí)行順序進行處理。因此,當自動提交打開或關(guān)閉時,將產(chǎn)生相同的結(jié)果。

例子

例如,要以原子方式遞增兩個計數(shù)器列,您可以執(zhí)行以下命令:

UPSERT INTO my_table(id, counter1, counter2) VALUES ('abc', 0, 0) ON DUPLICATE KEY UPDATE counter1 = counter1 + 1, counter2 = counter2 + 1;

僅更新尚不存在的列:

UPSERT INTO my_table(id, my_col) VALUES ('abc', 100) ON DUPLICATE KEY IGNORE;

請注意,在這個新子句中可以使用任意復(fù)雜的表達式:

UPSERT INTO my_table(id, total_deal_size, deal_size) VALUES ('abc', 0, 100) ON DUPLICATE KEY UPDATE total_deal_size = total_deal_size + deal_size, approval_reqd = CASE WHEN total_deal_size < 100 THEN AGEN_0deal0de '總規(guī)模<100 WHENVAL_DENONEPRO1 ' 否則“副總裁批準”結(jié)束;

限制

對 ON DUPLICATE KEY 子句的使用實施以下限制:

  • 主鍵列可能不會更新,因為這實際上是創(chuàng)建一個行。
  • 事務(wù)表可能不使用此子句,因為在發(fā)生沖突時通過異常處理已經(jīng)可以進行原子更新插入。
  • 不可變表可能不使用此子句,因為根據(jù)定義,不應(yīng)更新現(xiàn)有行
  • 當使用此子句時,可能不會在連接上設(shè)置 CURRENT_SCN 屬性,因為除非更新最新值,否則 HBase 不處理原子性。
  • 同一列不應(yīng)在同一語句中多次更新。
  • 子句中不允許聚合或引用序列。
  • 不支持原子更新的列上的全局索引,因為在行處于鎖定狀態(tài)時可能會跨線路進行單獨的 RPC 以維護二級索引。

本文摘自 :https://www.cnblogs.com/

開通會員,享受整站包年服務(wù)立即開通 >