為數據表開啟局部事務后,使用局部事務功能,您可以創建數據范圍在一個分區鍵值內的局部事務并對局部事務中的數據進行讀寫操作。通過使用局部事務您可以實現單行或多行讀寫的原子操作。
目前局部事務功能處于邀測中,默認關閉。如果需要使用該功能,請提交工單進行申請或者加入釘釘群36165029092(表格存儲技術交流群-3)進行咨詢。
使用局部事務可以指定某個分區鍵值內的操作是原子的,對分區鍵值內的數據進行的操作要么全部成功要么全部失敗,并且所提供的隔離級別為讀已提交。
前提條件
已初始化Client,詳情請參見初始化OTSClient。
使用方法
使用startLocalTransaction在指定的分區鍵值創建一個局部事務,并獲取局部事務ID。
對局部事務范圍內的數據進行讀寫操作。
支持對局部事務進行操作的接口為GetRow、PutRow、DeleteRow、UpdateRow、BatchWriteRow和GetRange。
使用commitTransaction提交局部事務或者使用abortTransaction丟棄局部事務。
注意事項
主鍵自增列功能和局部事務功能不能同時使用。
局部事務通過悲觀鎖(Pessimistic Lock)實現并發控制。
每個局部事務從創建開始生命周期最長為60秒。
如果超過60秒未提交局部事務或丟棄局部事務,則表格存儲服務端會認為此局部事務超時,并將局部事務丟棄。
如果創建局部事務時超時,則請求可能在表格存儲服務端已執行成功,此時請等待該局部事務超時后重新創建。
未提交的局部事務可能會失效,如果出現此情況,則需要重試該局部事務內的操作。
如果未對局部事務范圍內的數據進行寫操作,則提交局部事務或丟棄局部事務的操作是等同的。
在局部事務中讀寫數據有如下限制:
不能使用局部事務ID訪問局部事務范圍(即創建時使用的分區鍵值)以外的數據。
同一個局部事務中所有寫請求的分區鍵值必須與創建局部事務時的分區鍵值相同,讀請求則無此限制。
一個局部事務同時只能用于一個請求中,在使用局部事務期間,其他使用此局部事務ID的操作均會失敗。
每個局部事務中兩次讀寫操作的最大間隔為60秒。
如果超過60秒未操作局部事務,則表格存儲服務端會認為此局部事務超時,并將局部事務丟棄。
每個局部事務中寫入的數據量最大為4 MB,按正常的寫請求數據量計算規則累加。
如果在局部事務中寫入了未指定版本號的Cell,則該Cell的版本號會在寫入數據時(而非提交局部事務時)由表格存儲服務端自動生成,生成規則與正常寫入一個未指定版本號的Cell相同。
如果BatchWriteRow請求中帶有局部事務ID,則此請求中所有行只能操作該局部事務ID對應的表。
在使用局部事務期間,對應分區鍵值的數據會被加上寫鎖,只有持有局部事務ID在局部事務范圍內的寫請求才會成功。其他非事務請求或持有其他局部事務ID在局部事務范圍內的寫請求均會失敗。在局部事務提交、丟棄或超時后,對應的鎖也會被釋放。
帶有局部事務ID的讀寫請求失敗不會影響局部事務本身的存活情況,您可以指定重試規則進行重試或者主動丟棄當前局部事務。
接口
局部事務相關的startLocalTransaction、commitTransaction和abortTransaction的接口信息如下。
startLocalTransaction
/**
* 創建局部事務,獲取局部事務ID。
* @api
* @param [] $request
* 請求參數:數據表名稱、分區鍵。
* @return [] 請求返回。
* @throws OTSClientException 當參數檢查出錯或服務端返回校驗出錯時拋出異常。
* @throws OTSServerException 當OTS服務端返回錯誤時拋出異常。
* @example "src/examples/StartLocalTransaction.php" 50
*/
public function startLocalTransaction(array $request)
commitTransaction
/**
* 提交局部事務。
* @api
*
* @param [] $request
* 請求參數:局部事務ID。
* @return [] 請求返回。
* @throws OTSClientException 當參數檢查出錯或服務端返回校驗出錯時拋出異常。
* @throws OTSServerException 當OTS服務端返回錯誤時拋出異常。
* @example "src/examples/CommitTransaction.php" 50
*/
public function commitTransaction(array $request)
abortTransaction
/**
* 丟棄局部事務。
* @api
*
* @param [] $request
* 請求參數:局部事務ID。
* @return [] 請求返回。
* @throws OTSClientException 當參數檢查出錯或服務端返回校驗出錯時。
* @throws OTSServerException 當OTS服務端返回錯誤時。
* @example "src/examples/AbortTransaction.php" 20
*/
public function abortTransaction(array $request)
參數
參數 | 說明 |
table_name | 數據表名稱。 |
key | 數據表分區鍵。 創建局部事務時,只需要指定局部事務對應的分區鍵值。 |
primary_key | 數據表主鍵。 創建局部事務后,對局部事務范圍內的數據進行讀寫操作時,需要指定完整主鍵。 |
transaction_id | 局部事務ID,用于唯一標識一個局部事務。 創建局部事務后,操作局部事務時均需要帶上局部事務ID。 |
示例
使用局部事務寫入一行數據
以下示例用于為表的指定分區鍵創建一個局部事務后,在局部事務內寫入一行數據并提交事務。
// 獲取局部事務ID。
$response = $client->startLocalTransaction (array (
'table_name' => 'TransactionTable',
// 主鍵為[PK0:INTEGER,PK1:STRING]。
'key' => array(
array('PK0', 123)
)
));
$attr = array();
$attr[] = ['col0', 'bbb'];
$request = [
'table_name' => 'TransactionTable',
'condition' => RowExistenceExpectationConst::CONST_IGNORE, //condition可以為IGNORE、EXPECT_EXIST和EXPECT_NOT_EXIST。
// 設置主鍵。
'primary_key' => [
['PK0', 123],
['PK1', 'abc']
],
'attribute_columns' => $attr,
'transaction_id' => $response['transaction_id']
];
// 執行putRow方法寫入數據。
$client->putRow($request);
// 提交事務,使局部事務中的所有數據修改生效。您也可以通過丟棄事務來使數據寫入不生效。
$client->commitTransaction(array(
'transaction_id' => $response['transaction_id']
));
// 丟棄事務,局部事務中的所有數據修改均不會應用到原有數據。
// $client->abortTransaction(array(
// 'transaction_id' => $response['transaction_id']
// ));
使用局部事務讀取一行數據
以下示例用于為表的指定分區鍵創建一個局部事務后,在局部事務內讀取一行數據。
// 獲取局部事務ID。
$response = $client->startLocalTransaction (array (
'table_name' => 'TransactionTable',
// 主鍵為[PK0:INTEGER,PK1:STRING]。
'key' => array(
array('PK0', 123)
)
));
$request = array(
'table_name' => 'TransactionTable',
// 設置主鍵。
'primary_key' => array (
array('PK0', 123),
array('PK1', 'abc')
),
'max_versions' => 1,
'columns_to_get' => ['col0'],
'transaction_id' => $response['transaction_id']
);
// 執行getRow方法讀取數據。
$client->getRow($request);
// 提交或丟棄局部事務。對于讀操作來說,提交局部事務或丟棄局部事務的操作是等同的。
// 提交局部事務,使局部事務中的所有數據修改生效。
$client->commitTransaction(array(//提交事務
'transaction_id' => $response['transaction_id']
));
// 丟棄局部事務,局部事務中的所有數據修改均不會應用到原有數據。
// $client->abortTransaction(array(
// 'transaction_id' => $response['transaction_id']
// ));
相關文檔
如果要在局部事務內進行批量寫入、范圍讀取等操作,請在創建局部事務后,使用寫入數據或者讀取數據文檔中的相應操作示例以及在請求中帶上局部事務ID實現。