すべてのプロダクト
Search
ドキュメントセンター

Tablestore:ローカルトランザクション

最終更新日:May 08, 2025

データテーブルのローカルトランザクション機能を有効にすると、指定されたパーティションキー値に基づいてローカルトランザクションを作成し、ローカルトランザクション内のデータに対して読み取りおよび書き込み操作を実行できます。ローカルトランザクション機能を使用して、1 つ以上の行を読み書きするアトミック操作を実行できます。

ローカルトランザクションを使用すると、同じパーティションキーを共有するデータに対する操作がすべて成功するか、すべて失敗するかを指定できます。ローカルトランザクションの分離レベルは Read Committed です。

前提条件

  • クライアントが初期化されていること。詳細については、「Tablestore クライアントを初期化する」をご参照ください。

  • ローカルトランザクション機能が有効になっているデータテーブルが作成されていること。

    説明

    データテーブルを作成する際にローカルトランザクション機能を有効にしておらず、データテーブルの作成後にローカルトランザクション機能を使用する場合は、チケットを送信してください。

手順

  1. StartLocalTransaction 操作を呼び出して、指定されたパーティションキー値に基づいてローカルトランザクションを作成し、ローカルトランザクション ID を取得します。

  2. ローカルトランザクション内のデータを読み書きします。

    GetRow、PutRow、DeleteRow、UpdateRow、BatchWriteRow、および GetRange 操作を呼び出して、ローカルトランザクション内のデータに対して操作を実行できます。

  3. CommitTransaction 操作を呼び出してローカルトランザクションをコミットするか、AbortTransaction 操作を呼び出してローカルトランザクションを中止します。

使用上の注意

  • 自動採番主キー列機能とローカルトランザクション機能を同時に使用することはできません。

  • ローカルトランザクションでは、同時実行操作を制御するために悲観的ロックが使用されます。

  • ローカルトランザクションの有効期間は最大 60 秒です。

    ローカルトランザクションが 60 秒以内にコミットまたは中止されない場合、Tablestore サーバーはローカルトランザクションがタイムアウトしたと判断し、トランザクションを中止します。

  • タイムアウトエラーが返された場合でも、Tablestore サーバーでトランザクションが作成される場合があります。この場合、作成されたトランザクションがタイムアウトした後に、トランザクション作成リクエストを再送信できます。

  • ローカルトランザクションがコミットされていない場合、無効になる可能性があります。この場合、このトランザクション内の操作を再試行してください。

  • ローカルトランザクション内のデータに対して書き込み操作が実行されない場合、コミット操作と中止操作の効果は同じです。

  • Tablestore では、ローカルトランザクション内のデータに対する読み取りおよび書き込み操作に次の制限が課せられます。

    • ローカルトランザクション ID を使用して、トランザクションの作成に使用されたパーティションキー値に基づいて指定された範囲外のデータにアクセスすることはできません。

    • 同じトランザクション内のすべての書き込みリクエストのパーティションキー値は、トランザクションの作成に使用されたパーティションキー値と同じである必要があります。この制限は、読み取りリクエストには適用されません。

    • ローカルトランザクションは、一度に 1 つの リクエスト でのみ使用できます。ローカルトランザクションが使用中の場合、同じローカルトランザクション ID を使用する他の操作は失敗します。

    • ローカルトランザクション内のデータに対する 2 つの連続した読み取りまたは書き込み操作の最大間隔は 60 秒です。

      ローカルトランザクション内のデータに対して 60 秒以上読み取りまたは書き込み操作が実行されない場合、Tablestore サーバーはトランザクションがタイムアウトしたと判断し、トランザクションを中止します。

    • 各トランザクションに最大 4 MB のデータを書き込むことができます。各トランザクションに書き込まれるデータ量は、通常の書き込みリクエストと同じ方法で計算されます。

    • セルにバージョン番号を指定しない場合、Tablestore サーバーは、トランザクションのコミット時ではなく、セルがトランザクションに書き込まれたときに、通常の方法でセルにバージョン番号を自動的に割り当てます。

    • BatchWriteRow リクエストにローカルトランザクション ID が含まれている場合、リクエスト内のすべての行は、ローカルトランザクション ID に一致するテーブルにのみ書き込むことができます。

    • ローカルトランザクションを使用する場合、ローカルトランザクションの作成元のパーティションキー値のデータに書き込みロックが追加されます。ローカルトランザクション ID を含み、ローカルトランザクション内のデータの書き込みを開始する書き込みリクエストのみが成功します。他の非トランザクションリクエスト、または他のローカルトランザクションの ID を含み、ローカルトランザクション内のデータの書き込みを開始する書き込みリクエストは失敗します。ローカルトランザクション内のデータは、トランザクションがコミットまたは中止された場合、またはトランザクションがタイムアウトした場合にロック解除されます。

    • ローカルトランザクション ID を使用した読み取りまたは書き込みリクエストが拒否された場合でも、ローカルトランザクションは有効なままです。再試行ルールを指定してリクエストを再送信するか、トランザクションを中止することができます。

パラメータ

パラメータ

必須

説明

TableName

はい

データテーブルの名前。

PrimaryKey

はい

データテーブルのプライマリキー。

  • ローカルトランザクションを作成するときは、パーティションキー値を指定する必要があります。

  • ローカルトランザクション内のデータを読み書きするときは、すべてのプライマリキー列の値を指定する必要があります。

TransactionId

はい

ローカルトランザクションを一意に識別するローカルトランザクション ID。

ローカルトランザクション内のデータを読み書きするときは、ローカルトランザクション ID を指定する必要があります。

ローカルトランザクション機能を使用してデータの 1 行を書き込む

次のサンプルコードは、テーブル内の指定されたパーティションキー値に基づいてローカルトランザクションを作成し、ローカルトランザクション内にデータの 1 行を書き込む方法の例を示しています。ローカルトランザクション内にデータの 1 行が書き込まれた場合は、トランザクションをコミットします。そうでない場合は、トランザクションを破棄します。

func transactionPutRow(client *tablestore.TableStoreClient, tableName string) {
    // ローカルトランザクションのパーティションキー値を指定します。パーティションキーは最初のプライマリキー列です。
    transPk := new(tablestore.PrimaryKey)
    transPk.AddPrimaryKeyColumn("pk1", "pk1value")
    trans := &tablestore.StartLocalTransactionRequest{
        TableName:  tableName,
        PrimaryKey: transPk,
    }
    response, err := client.StartLocalTransaction(trans)
    if err != nil {
        fmt.Println("トランザクションの作成に失敗しました", err)
        return
    }
    // ローカルトランザクション ID を取得します。
    transId := response.TransactionId

    putPk := new(tablestore.PrimaryKey)
    putPk.AddPrimaryKeyColumn("pk1", "pk1value")
    putPk.AddPrimaryKeyColumn("pk2", int64(4))
    putRowChange := &tablestore.PutRowChange{
        TableName:  tableName,
        PrimaryKey: putPk,
    }
    putRowChange.AddColumn("col1", "col1data1")
    putRowChange.AddColumn("col2", int64(3))
    putRowChange.AddColumn("col3", []byte("test"))
    putRowChange.SetCondition(tablestore.RowExistenceExpectation_IGNORE)
    // ローカルトランザクション ID を指定します。これは、StartLocalTransactionResponse.TransactionId を使用して取得できます。
    putRowChange.TransactionId = transId
    putRowRequest := &tablestore.PutRowRequest{
        PutRowChange: putRowChange,
    }
    _, err = client.PutRow(putRowRequest)
    if err != nil {
        // ローカルトランザクションにデータの 1 行を書き込めなかった場合は、ローカルトランザクションを破棄します。この場合、ローカルトランザクション内のすべてのデータ変更は、データテーブル内のデータには適用されません。
        fmt.Println("putrow エラー:", err)
        request := &tablestore.AbortTransactionRequest{
            TransactionId: transId,
        }
        abortResponse, err := client.AbortTransaction(request)
        if err != nil {
            fmt.Println("トランザクションの中止に失敗しました エラー:", err)
        } else {
            fmt.Println("トランザクションの中止が完了しました。 RequestId は", abortResponse.RequestId)
        }
    } else {
        // ローカルトランザクションにデータの 1 行が書き込まれた場合は、ローカルトランザクションをコミットします。この場合、ローカルトランザクション内のすべてのデータ変更が有効になります。ローカルトランザクションを破棄して、ローカルトランザクション内のすべてのデータ変更を無効にすることができます。
        fmt.Println("putrow 完了")
        request := &tablestore.CommitTransactionRequest{
            TransactionId: transId,
        }
        commitResponse, err := client.CommitTransaction(request)
        if err != nil {
            fmt.Println("トランザクションのコミットに失敗しました エラー:", err)
        } else {
            fmt.Println("トランザクションのコミットが完了しました。 RequestId は", commitResponse.RequestId)
        }
    }
}

ローカルトランザクション機能を使用してデータの 1 行を読み取る

次のサンプルコードは、テーブル内の指定されたパーティションキー値に基づいてローカルトランザクションを作成し、ローカルトランザクション内のデータの 1 行を読み取る方法の例を示しています。

func transactionGetRow(client *tablestore.TableStoreClient, tableName string) {
    // ローカルトランザクションのパーティションキー値を指定します。パーティションキーは最初のプライマリキー列です。
    transPk := new(tablestore.PrimaryKey)
    transPk.AddPrimaryKeyColumn("pk1", "pk1value")
    trans := &tablestore.StartLocalTransactionRequest{
        TableName:  tableName,
        PrimaryKey: transPk,
    }
    response, err := client.StartLocalTransaction(trans)
    if err != nil {
        fmt.Println("トランザクションの作成に失敗しました", err)
        return
    }
    // ローカルトランザクション ID を取得します。
    transId := response.TransactionId

    // データを読み取ります。
    getRowPk := new(tablestore.PrimaryKey)
    getRowPk.AddPrimaryKeyColumn("pk1", "pk1value")
    getRowPk.AddPrimaryKeyColumn("pk2", int64(18))
    criteria := &tablestore.SingleRowQueryCriteria{
        PrimaryKey: getRowPk,
        TableName:  tableName,
        // 最新バージョンのデータを読み取ります。
        MaxVersion: 1,
        // ローカルトランザクション ID を指定します。
        TransactionId: transId,
    }
    getRowRequest := &tablestore.GetRowRequest{
        SingleRowQueryCriteria: criteria,
    }
    getResp, err := client.GetRow(getRowRequest)
    if err != nil {
        fmt.Println("getrow エラー:", err)
    } else {
        fmt.Println("get row col0 result is ", getResp.Columns[0].ColumnName, getResp.Columns[0].Value)
    }

    // ローカルトランザクションをコミットまたは破棄します。読み取り操作では、ローカルトランザクションのコミットと破棄の効果は同じです。
    // ローカルトランザクションをコミットして、ローカルトランザクション内のすべてのデータ変更を有効にします。
    request := &tablestore.CommitTransactionRequest{
        TransactionId: transId,
    }
    commitResponse, err := client.CommitTransaction(request)
    if err != nil {
        fmt.Println("トランザクションのコミットに失敗しました エラー:", err)
    } else {
        fmt.Println("トランザクションのコミットが完了しました。 RequestId は", commitResponse.RequestId)
    }
    // ローカルトランザクションを破棄します。この場合、ローカルトランザクション内のすべてのデータ変更は、データテーブル内のデータには適用されません。
    //request := &tablestore.AbortTransactionRequest{
    //    TransactionId: transId,
    //}
    //abortResponse, err := client.AbortTransaction(request)
    //if err != nil {
    //    fmt.Println("トランザクションの中止に失敗しました エラー:", err)
    //} else {
    //    fmt.Println("トランザクションの中止が完了しました。 RequestId は", abortResponse.RequestId)
    //}
}

関連情報

複数の行のデータを同時に書き込む場合、またはプライマリキー値が特定の範囲内にあるデータを読み取る場合は、ローカルトランザクションを作成します。次に、「データの書き込み」または「データの読み取り」のトピックに記載されているサンプルコードを参照して、ローカルトランザクション ID を含むリクエストを開始します。