PHP SQL Server: транзакция

Краткое описание: В этом руководстве вы узнаете, как выполнить транзакцию на SQL Server с помощью PHP PDO.

Этот урок начинается там, где закончился урок по удалению данных из таблицы в PHP.

Создание выборочных данных

Шаг 1. Откройте SQL Server Management Studio(SSMS) и подключитесь к базе данных BookStore на вашем SQL Server.

Шаг 2. Выполните следующие операторы, чтобы вставить книги в таблицу Books, назначить эти книги автору с идентификатором 2 и обновить инвентари для этих книг в таблице Inventories:

INSERT INTO Books(Title, Publisher, ISBN, PublishedDate) VALUES
('Mastering SQL: A Comprehensive Guide', 'Tech Books Publishing', '978-1234567890', '2022-01-15'),
('The Art of Database Design', 'Expert Press', '978-0987654321', '2021-06-10'),
('SQL Queries for Mere Mortals', 'Practical SQL Publishing', '978-1122334455', '2023-03-21'),
('Advanced SQL Programming Techniques', 'Pro Code Press', '978-6677889900', '2020-09-30'),
('Database Systems: Theory and Practice', 'Academic Press', '978-5566778899', '2022-11-05');
DECLARE @BookID1 INT, @BookID2 INT, @BookID3 INT, @BookID4 INT, @BookID5 INT;
SELECT @BookID1 = BookID FROM Books WHERE ISBN = '978-1234567890';
SELECT @BookID2 = BookID FROM Books WHERE ISBN = '978-0987654321';
SELECT @BookID3 = BookID FROM Books WHERE ISBN = '978-1122334455';
SELECT @BookID4 = BookID FROM Books WHERE ISBN = '978-6677889900';
SELECT @BookID5 = BookID FROM Books WHERE ISBN = '978-5566778899';
-- Insert records into the BookAuthors table
INSERT INTO BookAuthors(BookID, AuthorID)
VALUES(@BookID1, 2),
      (@BookID2, 2),
      (@BookID3, 2),
      (@BookID4, 2),
      (@BookID5, 2);
INSERT INTO Inventories(BookID, Qty)
SELECT BookID, ABS(CHECKSUM(NEWID()) % 101) + 100
FROM Books;
-- Insert customers
INSERT INTO [dbo].[Customers](FirstName, LastName, Email, PhoneNumber, Address) VALUES
('John', 'Doe', ' [email protected] ', '123-456-7890', '123 Elm Street, Springfield, IL 62701'),
('Jane', 'Smith', ' [email protected] ', '234-567-8901', '456 Oak Avenue, Metropolis, NY 10001');

Выполнение транзакции

Создайте новый файл orderdb.php и определите класс OrderDB, который обрабатывает транзакцию:

conn = $conn;
    }
    public function create($customerId, $bookId, $quantity, $price, $orderDate)
    {
        try {
            // Begin a transaction
            $this->conn->beginTransaction();
            // Check inventory
            $this->checkInventory($bookId, $quantity);
            // Insert order and get the new order ID
            $orderId = $this->insertOrder($customerId, $orderDate, $price * $quantity);
            // Insert order details
            $this->insertOrderDetails($orderId, $bookId, $quantity, $price);
            // Update inventory
            $this->updateInventory($bookId, $quantity);
            // Commit the transaction
            $this->conn->commit();
            return $orderId;
        } catch(Exception $e) {
            // Rollback the transaction on error
            $this->conn->rollBack();
            throw new Exception("Failed to create order: " . $e->getMessage());
        }
    }
    private function checkInventory($bookId, $quantity)
    {
        $sql = 'SELECT Qty FROM Inventories WHERE BookId = :bookId';
        $stmt = $this->conn->prepare($sql);
        $stmt->execute(['bookId' => $bookId]);
        $row = $stmt->fetch(PDO::FETCH_ASSOC);
        if($row === false || $row['Qty'] conn->prepare($sql);
        $stmt->execute([
            'orderDate' => $orderDate,
            'customerId' => $customerId,
            'totalAmount' => $totalAmount
        ]);
        return $this->conn->lastInsertId();
    }
    private function insertOrderDetails($orderId, $bookId, $quantity, $price)
    {
        $sql = 'INSERT INTO OrderDetails(OrderId, BookId, Quantity, Price) 
                VALUES(:orderId, :bookId, :quantity, :price)';
        $stmt = $this->conn->prepare($sql);
        $stmt->execute([
            'orderId' => $orderId,
            'bookId' => $bookId,
            'quantity' => $quantity,
            'price' => $price
        ]);
    }
    private function updateInventory($bookId, $quantity)
    {
        $sql = "UPDATE Inventories 
                SET Qty = Qty - :quantity 
                WHERE BookId = :bookId";
        $stmt = $this->conn->prepare($sql);
        $stmt->execute([
            'quantity' => $quantity,
            'bookId' => $bookId
        ]);
    }
}

Запуск приложения

Шаг 1. Измените файл index.php, чтобы создать заказ с помощью метода create() объекта OrderDB:

create(
    $customerId,
    $bookId,
    $quantity,
    $price,
    '2024-07-27'
);
echo "New Order ID: " . $orderId;

Шаг 2. Запустите index.php в веб-браузере. Он вернет следующий вывод:

New Order ID: 1

Это означает, что приложение успешно создало заказ с идентификатором 1.

Краткое содержание

  • Вызовите метод beginTransaction() объекта PDO, чтобы начать транзакцию.
  • Вызовите метод commit() объекта PDO, чтобы навсегда применить изменения к базе данных.
  • Вызовите метод rollback() объекта PDO для отката транзакции.
Мирослав С.

Автор статей, ИБ-специалист