Thứ tư, 25/03/2020 | 00:00 GMT+7
Một giao dịch MySQL là một group các lệnh SQL liên quan đến logic được thực thi trong database như một đơn vị duy nhất. Các giao dịch được sử dụng để thực thi tuân theo ACID [Tính nguyên tử, tính nhất quán, tính cách ly và độ bền] trong một ứng dụng. Đây là một bộ tiêu chuẩn chi phối độ tin cậy của các hoạt động xử lý trong database .
Tính nguyên tử đảm bảo sự thành công của các giao dịch liên quan hoặc thất bại hoàn toàn nếu xảy ra lỗi. Tính nhất quán đảm bảo tính hợp lệ của dữ liệu được gửi đến database theo logic nghiệp vụ đã xác định. Cách ly là việc thực hiện chính xác các giao dịch đồng thời đảm bảo các tác động của các client khác nhau kết nối với database không ảnh hưởng đến nhau. Độ bền đảm bảo các giao dịch liên quan đến lôgic vẫn ở trong database vĩnh viễn.
Các câu lệnh SQL được phát hành thông qua một giao dịch phải thành công hoặc thất bại hoàn toàn. Nếu bất kỳ truy vấn nào không thành công, MySQL sẽ khôi phục các thay đổi và chúng không bao giờ được commit với database .
Một ví dụ điển hình để hiểu cách giao dịch MySQL hoạt động là một trang web thương mại điện tử. Khi khách hàng đặt hàng, ứng dụng sẽ chèn các bản ghi vào một số bảng, chẳng hạn như: orders
và sản orders_products
orders
, tùy thuộc vào logic nghiệp vụ. Bản ghi nhiều bảng liên quan đến một đơn
hàng phải được gửi nguyên tử đến database dưới dạng một đơn vị logic duy nhất.
Một trường hợp sử dụng khác là trong một ứng dụng ngân hàng. Khi khách hàng chuyển tiền, một vài giao dịch sẽ được gửi đến database . Tài khoản của người gửi được ghi nợ và account của bên nhận được ghi có. Hai giao dịch phải được commit đồng thời. Nếu một trong số chúng không thành công, database sẽ trở lại trạng thái ban đầu và không có thay đổi nào được lưu vào đĩa.
Trong hướng dẫn này, bạn sẽ sử dụng Phần mở rộng PDO PHP , cung cấp giao diện để làm việc với database bằng PHP, để thực hiện các giao dịch MySQL trên server Ubuntu 18.04.
Yêu cầu
Trước khi bắt đầu, bạn cần những thứ sau:
- Một server Ubuntu 18.04 được cài đặt theo Cài đặt server ban đầu với Ubuntu 18.04 , bao gồm cả user không phải root có quyền sudo .
- Apache, MySQL và PHP được cài đặt trên hệ thống. Bạn có thể làm theo hướng dẫn về Cách cài đặt ngăn xếp Linux, Apache, MySQL, PHP [LAMP] trên Ubuntu 18.04 . Bạn có thể bỏ qua Bước 4 [ cài đặt server ảo] và làm việc trực tiếp với cài đặt Apache mặc định.
Bước 1 - Tạo database mẫu và bảng
Trước tiên, bạn sẽ tạo một database mẫu và thêm một số bảng trước khi bắt đầu làm việc với các giao dịch MySQL. Đầu tiên, đăng nhập vào server MySQL của bạn với quyền root :
- sudo mysql -u root -p
Khi được yêu cầu , hãy nhập password root MySQL của bạn và nhấn ENTER
để tiếp tục. Sau đó, tạo một database , với mục đích của hướng dẫn này, ta sẽ gọi database sample_store
:
- CREATE DATABASE sample_store;
Bạn sẽ thấy kết quả sau:
Output
Query OK, 1 row affected [0.00 sec]
Tạo một user được gọi là sample_user
cho
database của bạn. Hãy nhớ thay thế PASSWORD
bằng một giá trị mạnh:
- CREATE USER 'sample_user'@'localhost' IDENTIFIED BY 'PASSWORD';
Cấp đầy đủ các quyền cho user của bạn đối với database sample_store
:
- GRANT ALL PRIVILEGES ON sample_store.* TO 'sample_user'@'localhost';
Cuối cùng, reload các quyền MySQL:
- FLUSH PRIVILEGES;
Bạn sẽ thấy kết quả sau khi bạn đã tạo user của bạn :
Output
Query OK, 0 rows affected [0.01 sec] . . .
Với database và user tại chỗ, bây giờ bạn có thể tạo một số bảng để chứng minh cách hoạt động của các giao dịch MySQL.
Đăng xuất khỏi server MySQL:
- QUIT;
Sau khi hệ thống đăng xuất bạn, bạn sẽ thấy kết quả sau:
Output
Bye.
Sau đó, đăng nhập bằng thông tin đăng nhập của sample_user
mà bạn vừa tạo:
- sudo mysql -u sample_user -p
Nhập password cho sample_user
và nhấn ENTER
để tiếp tục.
Chuyển sang sample_store
để biến nó thành database hiện được chọn:
- USE sample_store;
Bạn sẽ thấy kết quả sau khi nó được chọn:
Output
Database Changed.
Tiếp theo, tạo bảng products
:
- CREATE TABLE products [product_id BIGINT PRIMARY KEY AUTO_INCREMENT, product_name VARCHAR[50], price DOUBLE] ENGINE = InnoDB;
Lệnh này tạo một bảng products
với một trường có tên product_id
. Bạn sử dụng kiểu dữ liệu BIGINT
có thể chứa giá trị lớn lên đến 2 ^ 63-1. Bạn sử dụng cùng trường
này làm PRIMARY KEY
để xác định duy nhất các sản phẩm. Từ khóa AUTO_INCREMENT
hướng dẫn MySQL tạo giá trị số tiếp theo khi các sản phẩm mới được chèn vào.
Trường product_name
thuộc loại VARCHAR
có thể chứa tối đa 50
chữ cái hoặc số. Đối với price
sản phẩm, bạn sử dụng kiểu dữ liệu DOUBLE
để phục vụ cho các định dạng dấu phẩy động trong giá có số thập phân.
Cuối cùng, bạn sử dụng InnoDB
làm ENGINE
vì nó hỗ trợ thoải mái các giao dịch MySQL thay vì các công cụ lưu trữ khác như MyISAM
.
Khi bạn đã tạo bảng products
của bạn , bạn sẽ nhận được kết quả sau:
Output
Query OK, 0 rows affected [0.02 sec]
Tiếp theo, thêm một số mục vào bảng products
bằng cách chạy các lệnh sau:
- INSERT INTO products[product_name, price] VALUES ['WINTER COAT','25.50'];
- INSERT INTO products[product_name, price] VALUES ['EMBROIDERED SHIRT','13.90'];
- INSERT INTO products[product_name, price] VALUES ['FASHION SHOES','45.30'];
- INSERT INTO products[product_name, price] VALUES ['PROXIMA TROUSER','39.95'];
Bạn sẽ thấy kết quả tương tự như sau sau mỗi thao tác INSERT
:
Output
Query OK, 1 row affected [0.02 sec] . . .
Sau đó, xác minh dữ liệu đã được thêm vào bảng sản phẩm:
- SELECT * FROM products;
Bạn sẽ thấy danh sách bốn sản phẩm mà bạn đã chèn:
Output
+------------+-------------------+-------+ | product_id | product_name | price | +------------+-------------------+-------+ | 1 | WINTER COAT | 25.5 | | 2 | EMBROIDERED SHIRT | 13.9 | | 3 | FASHION SHOES | 45.3 | | 4 | PROXIMA TROUSER | 39.95 | +------------+-------------------+-------+ 4 rows in set [0.01 sec]
Tiếp
theo, bạn sẽ tạo một bảng customers
để chứa thông tin cơ bản về khách hàng:
- CREATE TABLE customers [customer_id BIGINT PRIMARY KEY AUTO_INCREMENT, customer_name VARCHAR[50] ] ENGINE = InnoDB;
Như trong bảng products
, bạn sử dụng kiểu dữ liệu BIGINT
cho customer_id
và điều này sẽ đảm bảo bảng có thể hỗ trợ rất nhiều khách hàng lên đến 2 ^ 63-1 bản ghi. Từ khóa AUTO_INCREMENT
tăng giá trị của các cột khi bạn chèn khách hàng mới.
Vì cột customer_name
chấp nhận giá trị chữ và số, bạn sử dụng kiểu dữ liệu VARCHAR
với giới hạn
50
ký tự. , bạn sử dụng InnoDB
lưu trữ ENGINE
đến các giao dịch hỗ trợ.
Sau khi chạy lệnh trước đó để tạo bảng customers
, bạn sẽ thấy kết quả sau:
Output
Query OK, 0 rows affected [0.02 sec]
Bạn sẽ thêm ba khách hàng mẫu vào bảng. Chạy các lệnh sau:
- INSERT INTO customers[customer_name] VALUES ['JOHN DOE'];
- INSERT INTO customers[customer_name] VALUES ['ROE MARY'];
- INSERT INTO customers[customer_name] VALUES ['DOE JANE'];
Khi khách hàng đã được thêm vào, bạn sẽ thấy kết quả giống như sau :
Output
Query OK, 1 row affected [0.02 sec] . . .
Sau đó, xác minh dữ liệu trong bảng customers
:
- SELECT * FROM customers;
Bạn sẽ thấy danh sách ba khách hàng:
Output
+-------------+---------------+ | customer_id | customer_name | +-------------+---------------+ | 1 | JOHN DOE | | 2 | ROE MARY | | 3 | DOE JANE | +-------------+---------------+ 3 rows in set [0.00 sec]
Tiếp theo, bạn sẽ tạo một bảng orders
để ghi lại các đơn
đặt hàng của các khách hàng khác nhau. Để tạo bảng orders
, hãy thực hiện lệnh sau:
- CREATE TABLE orders [order_id BIGINT AUTO_INCREMENT PRIMARY KEY, order_date DATETIME, customer_id BIGINT, order_total DOUBLE] ENGINE = InnoDB;
Bạn sử dụng cột order_id
làm PRIMARY KEY
. Kiểu dữ liệu BIGINT
cho phép bạn chứa tối đa 2 ^ 63-1 đơn đặt hàng và sẽ tự động tăng lên sau mỗi lần chèn đơn đặt hàng. Trường order_date
sẽ chứa ngày và giờ thực tế đơn đặt hàng được đặt và do đó, bạn sử dụng DATETIME
dữ liệu DATETIME
. customer_id
liên quan đến bảng customers
mà bạn đã tạo trước đó.
Bạn sẽ thấy kết quả sau:
Output
Query OK, 0 rows affected [0.02 sec]
Vì đơn đặt hàng
của một khách hàng có thể chứa nhiều mặt hàng, bạn cần tạo một bảng orders_products
để chứa thông tin này.
Để tạo bảng orders_products
, hãy chạy lệnh sau:
- CREATE TABLE orders_products [ref_id BIGINT PRIMARY KEY AUTO_INCREMENT, order_id BIGINT, product_id BIGINT, price DOUBLE, quantity BIGINT] ENGINE = InnoDB;
Bạn sử dụng ref_id
làm PRIMARY KEY
và điều này sẽ tự động tăng lên sau mỗi lần chèn bản ghi. order_id
và product_id
tương ứng với các orders
và bảng products
. Cột price
thuộc loại dữ liệu DOUBLE
để chứa các giá trị thực.
Công cụ lưu trữ InnoDB
phải trùng với các bảng khác đã tạo trước đó vì đơn đặt hàng của một khách hàng
sẽ ảnh hưởng đến nhiều bảng đồng thời sử dụng các giao dịch.
Đầu ra của bạn sẽ xác nhận việc tạo bảng:
Output
Query OK, 0 rows affected [0.02 sec]
Hiện tại, bạn sẽ không thêm bất kỳ dữ liệu nào vào các bảng orders
và orders_products
nhưng bạn sẽ thực hiện việc này sau bằng cách sử dụng một tập lệnh PHP triển khai các giao dịch MySQL.
Đăng xuất khỏi server MySQL:
- QUIT;
Lược đồ database của bạn hiện đã hoàn tất và bạn đã điền vào nó một số bản ghi. Đến đây bạn sẽ tạo một lớp PHP để xử lý các kết nối database và các giao dịch MySQL.
Bước 2 - Thiết kế một lớp PHP để xử lý các giao dịch MySQL
Trong bước này, bạn sẽ tạo một lớp PHP sẽ sử dụng PDO [PHP Data Objects] để xử lý các giao dịch MySQL. Lớp sẽ kết nối với database MySQL của bạn và chèn dữ liệu nguyên tử vào database .
Lưu file lớp trong folder root của web server Apache của bạn. Để thực hiện việc này, hãy tạo file DBTransaction.php
bằng editor của bạn:
- sudo nano /var/www/html/DBTransaction.php
Sau
đó, thêm mã sau vào file . Thay thế PASSWORD
bằng giá trị bạn đã tạo ở Bước 1:
/var/www/html/DBTransaction.php