[PHP]db2_rollback関数の使い方とトランザクション管理の実践ガイド

PHP

こんにちは!今回は、PHPでDB2データベースのトランザクションを管理する際に重要なdb2_rollback関数について、詳しく解説していきます。

目次

  1. db2_rollback関数とは
  2. トランザクション管理の基礎
  3. 基本的な使い方
  4. 実践的な実装例
  5. エラーハンドリング
  6. ベストプラクティス

1. db2_rollback関数とは

db2_rollbackは、実行中のトランザクションを取り消し、データベースを前回のコミット時の状態に戻す関数です。構文は以下の通りです:

bool db2_rollback ( resource $connection )

2. トランザクション管理の基礎

2.1 トランザクションの重要性

  • データの整合性保持
  • 複数の操作をアトミックに実行
  • エラー発生時の安全な復帰

2.2 基本的な流れ

  1. トランザクション開始
  2. データベース操作
  3. 成功時:コミット
  4. 失敗時:ロールバック

3. 基本的な使い方

<?php
$conn = db2_connect($database, $user, $password);

// autocommitをオフにする
db2_autocommit($conn, DB2_AUTOCOMMIT_OFF);

try {
    // データベース操作
    $success = true;

    if ($success) {
        db2_commit($conn);
    } else {
        db2_rollback($conn);
    }
} catch (Exception $e) {
    db2_rollback($conn);
    throw $e;
}

4. 実践的な実装例

4.1 銀行送金処理の例

<?php
function transferMoney($conn, $from_account, $to_account, $amount) {
    try {
        db2_autocommit($conn, DB2_AUTOCOMMIT_OFF);

        // 送金元から引き落とし
        $sql1 = "UPDATE accounts SET balance = balance - ? WHERE account_id = ?";
        $stmt1 = db2_prepare($conn, $sql1);
        db2_execute($stmt1, array($amount, $from_account));

        // 送金先に入金
        $sql2 = "UPDATE accounts SET balance = balance + ? WHERE account_id = ?";
        $stmt2 = db2_prepare($conn, $sql2);
        db2_execute($stmt2, array($amount, $to_account));

        // 残高チェック
        $check_sql = "SELECT balance FROM accounts WHERE account_id = ?";
        $stmt3 = db2_prepare($conn, $check_sql);
        db2_execute($stmt3, array($from_account));
        $row = db2_fetch_assoc($stmt3);

        if ($row['BALANCE'] < 0) {
            throw new Exception("残高不足です");
        }

        db2_commit($conn);
        return true;

    } catch (Exception $e) {
        db2_rollback($conn);
        error_log("送金エラー: " . $e->getMessage());
        return false;
    }
}

4.2 在庫管理の例

<?php
function processOrder($conn, $order_id, $items) {
    try {
        db2_autocommit($conn, DB2_AUTOCOMMIT_OFF);

        foreach ($items as $item) {
            // 在庫チェック
            $stock_sql = "SELECT stock FROM inventory WHERE item_id = ?";
            $stmt1 = db2_prepare($conn, $stock_sql);
            db2_execute($stmt1, array($item['id']));
            $stock = db2_fetch_assoc($stmt1);

            if ($stock['STOCK'] < $item['quantity']) {
                throw new Exception("在庫不足: 商品ID " . $item['id']);
            }

            // 在庫更新
            $update_sql = "UPDATE inventory SET stock = stock - ? WHERE item_id = ?";
            $stmt2 = db2_prepare($conn, $update_sql);
            db2_execute($stmt2, array($item['quantity'], $item['id']));
        }

        db2_commit($conn);
        return true;

    } catch (Exception $e) {
        db2_rollback($conn);
        error_log("注文処理エラー: " . $e->getMessage());
        return false;
    }
}

5. エラーハンドリング

5.1 基本的なエラーチェック

<?php
if (!db2_rollback($conn)) {
    $error = db2_stmt_errormsg();
    error_log("ロールバック失敗: " . $error);
}

5.2 詳細なエラー情報の取得

<?php
function handleDbError($conn) {
    $error_msg = db2_stmt_errormsg();
    $error_state = db2_stmt_error();

    error_log("DB2エラー: [$error_state] $error_msg");
    db2_rollback($conn);
}

6. ベストプラクティス

  1. トランザクション境界の明確化
<?php
function doTransaction($conn, callable $callback) {
    try {
        db2_autocommit($conn, DB2_AUTOCOMMIT_OFF);
        $result = $callback();
        db2_commit($conn);
        return $result;
    } catch (Exception $e) {
        db2_rollback($conn);
        throw $e;
    }
}
  1. リソースの適切な解放
<?php
function cleanupResources($stmt, $conn) {
    if ($stmt) db2_free_stmt($stmt);
    if ($conn) db2_close($conn);
}

まとめ

db2_rollback関数を使用する際の重要なポイント:

  • トランザクションの境界を明確にする
  • 適切なエラーハンドリングを実装する
  • リソースの解放を忘れない
  • ビジネスロジックとトランザクション管理を分離する

関連情報

  • PHP公式マニュアル
  • IBM DB2トランザクション管理
  • データベーストランザクションのベストプラクティス

この記事が皆様のDB2データベース操作の参考になれば幸いです。
ご質問やご意見がございましたら、お気軽にコメントください!

タイトルとURLをコピーしました