[PHP]DB2トランザクション:db2_commit関数の完全解説!

PHP

こんにちは!今回は、PHPのdb2_commit関数について詳しく解説します。DB2データベースでのトランザクションをコミットするための重要な関数です。

1. db2_commit関数の基本情報

構文

db2_commit ( resource $connection ): bool

基本説明

  • データベーストランザクションをコミットします
  • 成功時はtrue、失敗時はfalseを返します
  • トランザクション内の変更を確定させます

2. 基本的な使用例

シンプルな使用例

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

if ($conn) {
    try {
        db2_autocommit($conn, DB2_AUTOCOMMIT_OFF);

        // SQLの実行
        db2_exec($conn, "UPDATE users SET status = 'active' WHERE id = 1");
        db2_exec($conn, "INSERT INTO logs (user_id, action) VALUES (1, 'activated')");

        // 変更をコミット
        if (db2_commit($conn)) {
            echo "トランザクションが正常にコミットされました";
        }
    } catch (Exception $e) {
        db2_rollback($conn);
        echo "エラー: " . $e->getMessage();
    }

    db2_close($conn);
}

3. 実践的な使用例

トランザクション管理クラス

<?php
class DB2TransactionManager {
    private $conn;
    private $isTransaction = false;

    public function __construct(resource $connection) {
        $this->conn = $connection;
    }

    public function beginTransaction(): bool {
        if (!$this->isTransaction) {
            db2_autocommit($this->conn, DB2_AUTOCOMMIT_OFF);
            $this->isTransaction = true;
            return true;
        }
        return false;
    }

    public function commit(): bool {
        if ($this->isTransaction) {
            if (db2_commit($this->conn)) {
                $this->isTransaction = false;
                db2_autocommit($this->conn, DB2_AUTOCOMMIT_ON);
                return true;
            }
            return false;
        }
        throw new RuntimeException("アクティブなトランザクションがありません");
    }

    public function rollback(): bool {
        if ($this->isTransaction) {
            if (db2_rollback($this->conn)) {
                $this->isTransaction = false;
                db2_autocommit($this->conn, DB2_AUTOCOMMIT_ON);
                return true;
            }
            return false;
        }
        throw new RuntimeException("アクティブなトランザクションがありません");
    }

    public function executeTransaction(callable $callback): mixed {
        $this->beginTransaction();

        try {
            $result = $callback($this->conn);
            $this->commit();
            return $result;
        } catch (Exception $e) {
            $this->rollback();
            throw $e;
        }
    }
}

バッチ処理での使用例

<?php
class DB2BatchProcessor {
    private $conn;
    private $batchSize;

    public function __construct(resource $connection, int $batchSize = 1000) {
        $this->conn = $connection;
        $this->batchSize = $batchSize;
    }

    public function processBatch(array $items, callable $processor): array {
        $results = [];
        $count = 0;

        db2_autocommit($this->conn, DB2_AUTOCOMMIT_OFF);

        try {
            foreach ($items as $item) {
                $processor($this->conn, $item);
                $count++;

                if ($count % $this->batchSize === 0) {
                    if (!db2_commit($this->conn)) {
                        throw new RuntimeException("バッチコミットに失敗しました");
                    }
                    $results[] = "Batch of {$this->batchSize} items committed";
                }
            }

            // 残りのアイテムをコミット
            if ($count % $this->batchSize !== 0) {
                if (!db2_commit($this->conn)) {
                    throw new RuntimeException("最終バッチのコミットに失敗しました");
                }
                $results[] = "Final batch committed";
            }

        } catch (Exception $e) {
            db2_rollback($this->conn);
            throw $e;
        } finally {
            db2_autocommit($this->conn, DB2_AUTOCOMMIT_ON);
        }

        return $results;
    }
}

複数データベース操作の同期

<?php
class DB2SyncManager {
    private $connections = [];

    public function addConnection(string $name, resource $connection): void {
        $this->connections[$name] = $connection;
    }

    public function syncOperation(array $operations): bool {
        // すべての接続でオートコミットをオフ
        foreach ($this->connections as $conn) {
            db2_autocommit($conn, DB2_AUTOCOMMIT_OFF);
        }

        try {
            // 各データベースで操作を実行
            foreach ($operations as $dbName => $operation) {
                if (!isset($this->connections[$dbName])) {
                    throw new RuntimeException("未知のデータベース接続: {$dbName}");
                }

                $operation($this->connections[$dbName]);
            }

            // すべての接続でコミット
            foreach ($this->connections as $conn) {
                if (!db2_commit($conn)) {
                    throw new RuntimeException("コミットに失敗しました");
                }
            }

            return true;
        } catch (Exception $e) {
            // エラー時はすべてロールバック
            foreach ($this->connections as $conn) {
                db2_rollback($conn);
            }
            throw $e;
        } finally {
            // オートコミットを元に戻す
            foreach ($this->connections as $conn) {
                db2_autocommit($conn, DB2_AUTOCOMMIT_ON);
            }
        }
    }
}

4. エラー処理

<?php
function safeCommit($conn): bool {
    try {
        if (!$conn) {
            throw new InvalidArgumentException("無効な接続リソース");
        }

        if (!db2_commit($conn)) {
            throw new RuntimeException(
                "コミットエラー: " . db2_stmt_errormsg()
            );
        }

        return true;
    } catch (Exception $e) {
        error_log("コミットエラー: " . $e->getMessage());
        return false;
    }
}

5. 注意点とTips

  1. トランザクション分離レベル
<?php
// トランザクション分離レベルの設定
db2_exec($conn, "SET TRANSACTION ISOLATION LEVEL READ COMMITTED");
  1. デッドロック対策
<?php
function executeWithDeadlockRetry(callable $operation, $maxRetries = 3): bool {
    $attempts = 0;

    while ($attempts < $maxRetries) {
        try {
            $operation();
            return true;
        } catch (Exception $e) {
            if (isDeadlockError($e) && $attempts < $maxRetries - 1) {
                $attempts++;
                sleep(1); // 再試行前に待機
                continue;
            }
            throw $e;
        }
    }

    return false;
}
  1. パフォーマンス最適化
  • 大きなトランザクションは適切なサイズに分割
  • 不必要なトランザクションの開始を避ける
  • コミット頻度の最適化

まとめ

db2_commit関数は、DB2データベースでのトランザクション管理において重要な役割を果たします。以下のような点に注意して使用しましょう:

  • トランザクションの適切な範囲設定
  • エラー処理の実装
  • デッドロック対策
  • パフォーマンスの最適化

適切なトランザクション管理は、データの整合性を保ちながら、効率的なデータベース操作を実現するために不可欠です。

ぜひ、これらの例を参考に、みなさんのプロジェクトでも活用してみてください!

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