使用局部事務功能,建立資料範圍在一個分區索引值內的局部事務。對局部事務中的資料進行讀寫操作後,可以根據實際提交或者丟棄局部事務。局部事務通過悲觀鎖(Pessimistic Lock)實現並發控制。

目前局部事務功能處於邀測中,預設關閉。如果需要使用該功能,請提交工單進行申請。

使用局部事務可以指定某個分區索引值內的操作是原子的,對分區索引值內的資料進行的操作要麼全部成功要麼全部失敗,並且所提供的隔離等級為讀已提交。

前提條件

  • 已初始化Client,詳情請參見初始化
  • 已建立資料表並寫入資料。

使用方法

  1. 使用start_local_transaction在指定的分區索引值建立一個局部事務,並擷取局部事務ID。
  2. 對局部事務範圍內的資料進行讀寫操作。

    支援對局部事務進行操作的介面為GetRow、PutRow、DeleteRow、UpdateRow、BatchWriteRow和GetRange。

  3. 使用commit_transaction提交局部事務或者使用abort_transaction丟棄局部事務。

限制

  • 每個局部事務從建立開始生命週期最長為60秒。

    如果超過60秒未提交或丟棄局部事務,Tablestore服務端會認為此局部事務逾時,並將局部事務丟棄。

  • 如果建立局部事務時逾時,此請求可能在Tablestore服務端已執行成功,此時使用者需要等待該局部事務逾時後重新建立。
  • 未提交的局部事務可能失效,如果出現此情況,需要重試該局部事務內的操作。
  • 在局部事務中讀寫資料有如下限制:
    • 不能使用局部事務ID訪問局部事務範圍(即建立時使用的分區索引值)以外的資料。
    • 同一個局部事務中所有寫請求的分區索引值必須與建立局部事務時的分區索引值相同,讀請求則無此限制。
    • 一個局部事務同時只能用於一個請求中,在使用局部事務期間,其它使用此局部事務ID的操作均會失敗。
    • 每個局部事務中兩次讀寫操作的最大間隔為60秒。

      如果超過60秒未操作局部事務,Tablestore服務端會認為此局部事務逾時,並將局部事務丟棄。

    • 每個局部事務中寫入的資料量最大為4 MB,按正常的寫請求資料量計算規則累加。
    • 如果在局部事務中寫入了未指定版本號碼的Cell,該Cell的版本號碼會在寫入時(而非提交時)由Tablestore服務端自動產生,建置規則與正常寫入一個未指定版本號碼的Cell相同。
    • 如果BatchWriteRow請求中帶有局部事務ID,則此請求中所有行只能操作該局部事務ID對應的表。
    • 在使用局部事務期間,對應分區索引值的資料會被上寫鎖,只有持有局部事務ID在局部事務範圍內的寫請求才會成功。其它非事務請求或持有其他局部事務ID在局部事務範圍內的寫請求均會失敗。在局部事務提交、丟棄或逾時後,對應的鎖也會被釋放。
    • 帶有局部事務ID的讀寫請求失敗不會影響局部事務本身的存活情況,您可以指定重試規則進行重試或者主動丟棄當前局部事務。

參數

參數 說明
table_name 資料表名稱。
key 資料表分區鍵。

建立局部事務時,只需要指定局部事務對應的分區索引值。

primary_key 資料表主鍵。

建立局部事務後,對局部事務範圍內的資料進行讀寫操作時,需要指定完整主鍵。

transaction_id 局部事務ID,用於唯一標識一個局部事務。

建立局部事務後,操作局部事務時均需要帶上局部事務ID。

樣本

  1. 調用start_local_transaction方法使用指定分區索引值建立一個局部事務,並擷取局部事務ID。
    # 在PK0下建立局部事務。
    key = [('PK0', 1)]
    # start_local_transaction方法的傳回值即為transaction_id。
    transaction_id = client.start_local_transaction(table_name, key)
  2. 對局部事務範圍內的資料進行讀寫操作。

    對局部事務範圍內資料的讀寫操作與正常讀寫資料操作基本相同,只需填入局部事務ID即可。

    • 寫入一行資料。
      primary_key = [('PK0', 1), ('PK1', 'transaction')]
      attribute_columns = [('value', 'origion value')]
      row = Row(primary_key, attribute_columns)
      condition = Condition(RowExistenceExpectation.IGNORE)
      consumed, return_row = client.put_row(table_name, row, condition)
    • 讀取此行資料。
      primary_key = [('PK0', 1), ('PK1', 'transaction')]
      columns_to_get = ['value']
      
      consumed, return_row, next_token = client.get_row(
          table_name, primary_key, columns_to_get, None, 1, None, None, None, None, transaction_id
      )
      
      for att in return_row.attribute_columns:
          print ('\tname:%s\tvalue:%s' % (att[0], att[1]))
  3. 提交或丟棄局部事務。
    • 提交局部事務,使局部事務中的所有資料修改生效。
      client.commit_transaction(transaction_id)
    • 丟棄局部事務,局部事務中的所有資料修改均不會應用到原有資料。
      client.abort_transaction(transaction_id)