Database
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Database

Hiểu các giao dịch trong SQL

Giao dịch trong SQL là một đơn vị thực thi nhóm một hoặc nhiều tác vụ lại với nhau. Một giao dịch được coi là thành công nếu tất cả các tác vụ bên trong nó được thực hiện mà không có lỗi.

Tuy nhiên, nếu bất kỳ tác vụ nào trong một giao dịch không thực hiện được thì toàn bộ giao dịch sẽ không thành công. Một giao dịch chỉ có hai kết quả:thành công hoặc thất bại.

Một tình huống thực tế

Hãy xem xét một ví dụ thực tế về máy ATM (Máy rút tiền tự động). Bạn đến máy ATM và nó yêu cầu thẻ của bạn. Nó chạy một truy vấn để kiểm tra xem thẻ có hợp lệ hay không. Tiếp theo, nó yêu cầu bạn nhập mã pin của bạn. Một lần nữa, nó chạy một truy vấn để khớp với mã pin. Sau đó, máy ATM sẽ hỏi bạn số tiền bạn muốn rút và bạn nhập số tiền bạn muốn. Máy ATM thực hiện một truy vấn khác để khấu trừ số tiền đó từ tài khoản của bạn và sau đó phân phối tiền cho bạn.

Điều gì sẽ xảy ra nếu số tiền bị trừ trong tài khoản của bạn và sau đó hệ thống bị treo do mất điện mà không phân phối các ghi chú?

Đây là vấn đề vì khách hàng bị trừ tiền mà chưa nhận được tiền. Đây là nơi mà các giao dịch có thể thuận tiện.

Trong trường hợp hệ thống gặp sự cố hoặc bất kỳ lỗi nào khác, tất cả các tác vụ trong giao dịch sẽ được khôi phục. Do đó, trong trường hợp máy ATM, số tiền sẽ được cộng vào tài khoản của bạn nếu bạn không thể rút tiền vì bất kỳ lý do gì.

Giao dịch là gì?

Nói một cách đơn giản nhất, sự thay đổi trong bảng cơ sở dữ liệu là một giao dịch. Do đó, các câu lệnh INSERT, UPDATE và DELETE đều là các câu lệnh giao dịch. Khi bạn viết một truy vấn, một giao dịch sẽ được thực hiện. Tuy nhiên, giao dịch này không thể bị đảo ngược. Chúng ta sẽ xem cách các giao dịch được tạo, cam kết và khôi phục bên dưới nhưng trước tiên, hãy tạo một số dữ liệu giả để hoạt động.

Chuẩn bị Dữ liệu

Chạy tập lệnh sau trên máy chủ cơ sở dữ liệu của bạn.

CREATE DATABASE schooldb

CREATE TABLE student
(
    id INT PRIMARY KEY,
    name VARCHAR(50) NOT NULL,
    gender VARCHAR(50) NOT NULL,
    age INT NOT NULL,
    total_score INT NOT NULL,
    
 )

INSERT INTO student 

VALUES (1, 'Jolly', 'Female', 20, 500), 
(2, 'Jon', 'Male', 22, 545), 
(3, 'Sara', 'Female', 25, 600), 
(4, 'Laura', 'Female', 18, 400), 
(5, 'Alan', 'Male', 20, 500)

Tập lệnh SQL trên tạo một trường cơ sở dữ liệu. Trong cơ sở dữ liệu này, một sinh viên bảng được tạo và một số dữ liệu giả được thêm vào bảng đó.

Thực thi Truy vấn mà không có Giao dịch

Hãy để chúng tôi thực hiện ba truy vấn tiêu chuẩn. Chúng tôi không sử dụng giao dịch vào lúc này.

INSERT INTO student 
VALUES (6, 'Suzi', 'Female', 25, 395)

UPDATE student
SET age = 'Six' WHERE id= 6

DELETE from student
WHERE id = 6

Tại đây, truy vấn đầu tiên sẽ chèn hồ sơ học sinh vào cơ sở dữ liệu. Truy vấn thứ hai cập nhật tuổi của học sinh và truy vấn thứ ba xóa bản ghi mới được chèn.

Nếu bạn thực hiện đoạn mã trên, bạn sẽ thấy rằng bản ghi sẽ được chèn vào cơ sở dữ liệu và sau đó sẽ xảy ra lỗi khi thực hiện truy vấn thứ hai.

Nếu bạn nhìn vào truy vấn thứ hai, chúng tôi đang cập nhật tuổi bằng cách lưu trữ giá trị chuỗi trong cột tuổi có thể lưu trữ dữ liệu kiểu số nguyên. Do đó một lỗi sẽ được ném ra. Tuy nhiên, truy vấn đầu tiên vẫn sẽ hoàn thành thành công. Điều này có nghĩa là nếu bạn chọn tất cả các bản ghi từ bảng sinh viên, bạn sẽ thấy bản ghi mới được chèn vào.

[table id =23 /]

Bạn có thể thấy rằng bản ghi có id =6 và tên ‘Suzi’ đã được chèn vào cơ sở dữ liệu. Nhưng không thể cập nhật tuổi và truy vấn thứ hai không thành công.

Nếu chúng ta không muốn điều này thì sao? Điều gì sẽ xảy ra nếu chúng ta muốn chắc chắn rằng tất cả các truy vấn đều thực thi thành công hoặc không có truy vấn nào thực thi? Đây là lúc các giao dịch trở nên hữu ích.

Thực thi Truy vấn với Giao dịch

Bây giờ chúng ta hãy thực hiện ba truy vấn ở trên trong một giao dịch.

Trước tiên, hãy xem cách tạo và thực hiện một giao dịch.

Tạo Giao dịch

Để chạy một truy vấn / truy vấn như một giao dịch, chỉ cần đặt các truy vấn trong các từ khóa BẮT ĐẦU GIAO DỊCH và GIAO DỊCH CAM KẾT. GIAO DỊCH BẮT ĐẦU tuyên bố bắt đầu GIAO DỊCH trong khi GIAO DỊCH CAM KẾT tuyên bố rằng giao dịch đã được hoàn thành.

Hãy thực hiện ba truy vấn mới trên cơ sở dữ liệu mà chúng tôi đã tạo trước đó dưới dạng một giao dịch. Chúng tôi sẽ thêm một hồ sơ mới cho một sinh viên mới có ID 7.

BEGIN TRANSACTION

	INSERT INTO student 
	VALUES (7, 'Jena', 'Female', 22, 456)

	UPDATE student
	SET age = 'Twenty Three' WHERE id= 7

	DELETE from student
	WHERE id = 7

COMMIT TRANSACTION

Khi giao dịch trên được thực hiện, một lần nữa lỗi sẽ xảy ra trong truy vấn thứ hai vì một giá trị kiểu chuỗi lại được lưu trữ trong cột tuổi chỉ lưu trữ dữ liệu kiểu số nguyên.

Tuy nhiên, vì lỗi xảy ra bên trong giao dịch, nên tất cả các truy vấn đã thực hiện thành công trước khi xảy ra lỗi này sẽ tự động được khôi phục. Do đó, truy vấn đầu tiên chèn hồ sơ sinh viên mới có id =7 và tên ‘Jena’ cũng sẽ được khôi phục.

Bây giờ, nếu bạn chọn tất cả các bản ghi từ bảng sinh viên, bạn sẽ thấy rằng bản ghi mới cho ‘Jena’ chưa được chèn.

Khôi phục giao dịch thủ công

Chúng tôi biết nếu một truy vấn gây ra lỗi trong một giao dịch, thì toàn bộ giao dịch, bao gồm tất cả các truy vấn đã được thực hiện, sẽ tự động được khôi phục. Tuy nhiên, chúng tôi cũng có thể khôi phục giao dịch theo cách thủ công bất cứ khi nào chúng tôi muốn.

Để khôi phục một giao dịch, từ khóa ROLLBACK được sử dụng theo sau là tên của giao dịch. Để đặt tên cho một giao dịch, cú pháp sau được sử dụng:

BEGIN TRANSACTION Transaction_name

Giả sử chúng ta muốn bảng học sinh của mình không có bản ghi nào chứa tên học sinh trùng lặp. Chúng tôi sẽ thêm một bản ghi cho một học sinh mới. Sau đó, chúng tôi sẽ kiểm tra xem trong cơ sở dữ liệu có tồn tại một học sinh có tên trùng với tên của học sinh mới được chèn hay không. Nếu học sinh có tên đó chưa tồn tại, chúng tôi sẽ thực hiện giao dịch của mình. Nếu một sinh viên có tên đó tồn tại, chúng tôi sẽ khôi phục giao dịch của mình. Chúng tôi sẽ sử dụng các câu lệnh điều kiện trong truy vấn của chúng tôi.

Hãy xem giao dịch sau:

DECLARE @NameCount int

BEGIN TRANSACTION AddStudent

	INSERT INTO student 
	VALUES (8, 'Jacob', 'Male', 21, 600)

	SELECT @NameCount = COUNT(*) FROM student WHERE name = 'Jacob'

	IF @NameCount > 1
		BEGIN 
			ROLLBACK TRANSACTION AddStudent
			PRINT 'A student with this name already exists'
		END
	ELSE
		BEGIN
			COMMIT TRANSACTION AddStudent
			PRINT 'New record added successfully'
		END

Hãy xem kỹ đoạn script trên. Rất nhiều thứ đang xảy ra ở đây.

Trong dòng đầu tiên, chúng ta tạo một biến SQL NameCount kiểu số nguyên.

Tiếp theo, chúng tôi bắt đầu một giao dịch có tên là ‘AddStudent’. Bạn có thể đặt bất kỳ tên nào cho giao dịch của mình.

Bên trong giao dịch, chúng tôi đã chèn một bản ghi mới cho một sinh viên có id =8 và tên là ‘Jacob’.

Tiếp theo, sử dụng hàm tổng hợp COUNT, chúng tôi đếm số lượng hồ sơ sinh viên có tên là ‘Jacob’ và lưu trữ kết quả trong biến ‘NameCount’.

Nếu giá trị của biến lớn hơn 1, điều đó có nghĩa là học sinh có tên ‘Jacob’ đã tồn tại trong cơ sở dữ liệu. Trong trường hợp đó, chúng tôi QUAY LẠI giao dịch của mình và IN một thông báo trên màn hình rằng "Một học sinh có tên này đã tồn tại".

Nếu không, chúng tôi thực hiện giao dịch của mình và hiển thị thông báo "Đã thêm bản ghi mới thành công".

Khi bạn chạy giao dịch trên lần đầu tiên, sẽ không có hồ sơ sinh viên có tên ‘Jacob’. Do đó, giao dịch sẽ được cam kết và thông báo sau sẽ được in:

Bây giờ hãy thử chạy tập lệnh SQL sau trên máy chủ:

DECLARE @NameCount int

BEGIN TRANSACTION AddStudent

	INSERT INTO student 
	VALUES (9, 'Jacob', 'Male', 22, 400)

	SELECT @NameCount = COUNT(*) FROM student WHERE name = 'Jacob'

	IF @NameCount > 1
		BEGIN 
			ROLLBACK TRANSACTION AddStudent
			PRINT 'A student with this name already exists'
		END
	ELSE
		BEGIN
			COMMIT TRANSACTION
			PRINT 'New record added successfully'
		END

Ở đây một lần nữa, chúng tôi đang chèn hồ sơ sinh viên có id =9 và tên là ‘Jacob’. Vì hồ sơ sinh viên có tên ‘Jacob’ đã tồn tại trong cơ sở dữ liệu, giao dịch sẽ quay trở lại và thông báo sau sẽ được in:

Các liên kết hữu ích

  • Các lớp về giao dịch SQL

  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Đổi tên các chỉ mục bằng thủ tục sp_rename

  2. Toán tử so sánh SQL

  3. Triển khai Cơ sở dữ liệu từ Kiểm soát Nguồn

  4. Đơn giản hóa quy trình kiểm tra đơn vị được lưu trữ chính còn gọi là thủ tục tiện ích

  5. Điều chỉnh hiệu suất Knee-Jerk:Chỉ cần thêm ổ SSD