Go SDK 可在指定分區索引值範圍內執行局部事務,使事務內的寫操作全部提交或全部丟棄,隔離等級為讀已提交(Read Committed)。
前提條件
-
安裝Tablestore Go SDK並初始化用戶端。局部事務需要 1.7.8 及以上版本,建議使用最新版本。
-
資料表已開啟局部事務。建立資料表時可通過
EnableLocalTxn開啟;如果需要確認已有資料表是否開啟局部事務,或為已有資料表開啟該功能,請提交工單。
功能說明
局部事務的作用範圍限定在單個分區索引值內。事務內的讀寫請求共用同一個事務 ID,操作分為以下三個階段:
-
調用
StartLocalTransaction並傳入分區索引值,建立局部事務並擷取事務 ID。 -
在事務內執行
GetRow、PutRow、UpdateRow、DeleteRow、BatchWriteRow或GetRange,並在請求中攜帶事務 ID。 -
調用
CommitTransaction提交事務使修改生效,或調用AbortTransaction丟棄事務和所有修改。
func (client *TableStoreClient) StartLocalTransaction(request *StartLocalTransactionRequest) (*StartLocalTransactionResponse, error)
func (client *TableStoreClient) CommitTransaction(request *CommitTransactionRequest) (*CommitTransactionResponse, error)
func (client *TableStoreClient) AbortTransaction(request *AbortTransactionRequest) (*AbortTransactionResponse, error)
以下樣本為分區索引值 user-a 建立局部事務,在事務內寫入一行資料,然後提交事務。
partitionKey := &tablestore.PrimaryKey{}
partitionKey.AddPrimaryKeyColumn("user_id", "user-a")
startResponse, err := client.StartLocalTransaction(
&tablestore.StartLocalTransactionRequest{
TableName: "example_table",
PrimaryKey: partitionKey,
},
)
if err != nil {
log.Fatal(err)
}
transactionID := startResponse.TransactionId
rowKey := &tablestore.PrimaryKey{}
rowKey.AddPrimaryKeyColumn("user_id", "user-a")
rowKey.AddPrimaryKeyColumn("record_id", int64(1))
change := &tablestore.PutRowChange{
TableName: "example_table",
PrimaryKey: rowKey,
TransactionId: transactionID,
}
change.AddColumn("status", "created")
change.SetCondition(tablestore.RowExistenceExpectation_IGNORE)
_, err = client.PutRow(&tablestore.PutRowRequest{PutRowChange: change})
if err != nil {
_, _ = client.AbortTransaction(
&tablestore.AbortTransactionRequest{TransactionId: transactionID},
)
log.Fatal(err)
}
_, err = client.CommitTransaction(
&tablestore.CommitTransactionRequest{TransactionId: transactionID},
)
if err != nil {
log.Fatal(err)
}
參數說明
建立局部事務
StartLocalTransactionRequest 包含以下參數。
|
名稱 |
類型 |
說明 |
|
TableName(必選) |
|
資料表名稱。 |
|
PrimaryKey(必選) |
|
用於限定事務範圍的分區索引值。只設定資料表的第一個主鍵列。 |
事務內資料操作
事務內的 PutRowChange、UpdateRowChange、DeleteRowChange、SingleRowQueryCriteria 或 RangeRowQueryCriteria 包含以下公用參數。
|
名稱 |
類型 |
說明 |
|
TransactionId(必選) |
|
|
提交或丟棄局部事務
CommitTransactionRequest 和 AbortTransactionRequest 包含以下參數。
|
名稱 |
類型 |
說明 |
|
TransactionId(必選) |
|
要提交或丟棄的局部事務 ID。 |
傳回值
StartLocalTransactionResponse 包含以下商務資訊。
|
欄位 |
類型 |
說明 |
|
|
|
建立的局部事務 ID,用於事務內的資料操作以及提交或丟棄事務。 |
使用限制
-
主鍵列自增和局部事務不能同時使用。
-
局部事務通過悲觀鎖實現並發控制。事務期間,指定分區索引值的資料會被加寫鎖,只有攜帶該事務 ID 的寫請求可以成功。提交、丟棄或逾時後,服務端釋放寫鎖。
-
事務生命週期最長為 60 秒。兩次操作間隔超過 60 秒時,服務端自動丟棄事務。
-
建立局部事務時如果請求逾時,事務可能已在服務端建立成功。等待該事務逾時後,再重新建立事務。
-
未提交的局部事務可能失效。如果事務失效,需要重試事務內的操作。
-
同一時間只能有一個請求使用事務 ID,並發使用同一事務 ID 的請求均失敗。
-
事務內寫請求的分區索引值必須與建立事務時一致;讀請求不受此限制。
-
使用
BatchWriteRow在事務內批量寫入時,請求中的所有行只能操作該事務對應的資料表。 -
單個事務最多寫入 4 MB 資料,資料量按普通寫請求的計算規則累加。
-
事務內寫入屬性列時未指定版本號碼的,版本號碼在寫入時由服務端按普通寫入的規則產生,而不是在提交事務時產生。
-
事務內讀寫請求失敗不會使事務失效,可以重試請求或主動丟棄事務。
情境樣本
在局部事務內讀取一行資料
以下樣本在已建立的局部事務內讀取一行資料。唯讀事務的提交和丟棄效果相同,都會釋放事務。
criteria := &tablestore.SingleRowQueryCriteria{
TableName: "example_table",
PrimaryKey: rowKey,
MaxVersion: 1,
TransactionId: transactionID,
}
response, err := client.GetRow(
&tablestore.GetRowRequest{SingleRowQueryCriteria: criteria},
)
if err != nil {
log.Fatal(err)
}
fmt.Println(response.Columns)
_, err = client.CommitTransaction(
&tablestore.CommitTransactionRequest{TransactionId: transactionID},
)
if err != nil {
log.Fatal(err)
}