Có phải là một thực tế xấu để luôn luôn tạo ra một giao dịch?


88

Có phải là một thực tế xấu để luôn luôn tạo ra một giao dịch?

Ví dụ, đó là một thực hành tốt để tạo ra một giao dịch không có gì ngoài một đơn giản SELECT?

Chi phí tạo giao dịch khi không thực sự cần thiết là bao nhiêu?

Ngay cả khi bạn đang sử dụng một mức cô lập như thế READ UNCOMMITTED, nó có phải là một thực hành xấu?


1
Nhìn vào tác động của BEGIN TRAN SELECT ... COMMITvs chỉ SELECTcó một sự khác biệt hiệu suất cực kỳ nhỏ .
Martin Smith

Câu trả lời:


100

Là một thực hành xấu để tạo ra một giao dịch luôn?

Nó phụ thuộc vào bối cảnh bạn đang nói ở đây. Nếu đó là một bản cập nhật, thì tôi thực sự khuyên bạn nên sử dụng GIAO DỊCH một cách rõ ràng. Nếu nó là CHỌN thì KHÔNG (rõ ràng).

Nhưng chờ đã có nhiều điều để hiểu trước: Mọi thứ trong máy chủ sql đều được chứa trong một giao dịch.

Khi tùy chọn phiên IMPLICIT_TRANSACTIONSOFFvà bạn chỉ định rõ ràng begin trancommit/rollbacksau đó, điều này thường được gọi là Giao dịch rõ ràng . Nếu không, bạn nhận được một giao dịch tự động.

Khi IMPLICIT_TRANSACTIONSđược ONmột giao dịch ngầm sẽ tự động bắt đầu khi thực hiện một trong những loại tuyên bố được ghi lại trong sách bài trực tuyến (ví dụ SELECT/ UPDATE/ CREATE) và nó phải được cam kết hoặc cuộn lại một cách rõ ràng. Thực hiện một BEGIN TRANtrong chế độ này sẽ tăng lên @@TRANCOUNTvà bắt đầu một giao dịch "lồng nhau" khác)

Để chuyển chế độ bạn đang sử dụng, bạn sẽ sử dụng

SET IMPLICIT_TRANSACTIONS ON

hoặc là

SET IMPLICIT_TRANSACTIONS OFF

select @@OPTIONS & 2

nếu ở trên trả về 2, bạn đang ở chế độ giao dịch ngầm. Nếu nó trả về 0, bạn đang ở chế độ tự động.

Chi phí tạo giao dịch là bao nhiêu khi không thực sự cần thiết?

Các giao dịch là cần thiết để đưa cơ sở dữ liệu từ một trạng thái nhất quán sang một trạng thái nhất quán khác. Giao dịch không có chi phí vì không có thay thế cho giao dịch. Tham khảo: Sử dụng các mức cô lập dựa trên phiên bản hàng

Ngay cả khi bạn đang sử dụng mức cô lập read_uncomited. Là một thực hành xấu? bởi vì nó không có vấn đề với khóa.

Mức cô lập READ_UNCOMMITED sẽ cho phép đọc bẩn theo định nghĩa, tức là Một giao dịch sẽ có thể thấy các thay đổi không được cam kết thực hiện bởi giao dịch khác. Mức cô lập này là gì, nó giúp thư giãn đầu khóa - phương pháp thu được các khóa để bảo vệ đồng thời cơ sở dữ liệu.

Bạn có thể sử dụng điều này ở cấp độ kết nối / truy vấn, để nó không ảnh hưởng đến các truy vấn khác.

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

Tìm thấy một bài viết thú vị của Jeff Atwood mô tả Deadlocks do Puzzle Philosophers Puzzle và mô tả đọc mức độ cô lập ảnh chụp cam kết .

BIÊN TẬP:

Vì tò mò, tôi đã thực hiện một số thử nghiệm đo lường tác động lên nhật ký T với các bộ đếm Perfmon như Log Bytes Flushed / Sec, Log Flush Waits / Sec (Số lần xác nhận mỗi giây đang chờ trên LOG tuôn ra) như biểu đồ bên dưới:

nhập mô tả hình ảnh ở đây

mã mẫu:

create table testTran (id int, Name varchar(8))
go

-- 19 sec
-- Autocommit transaction
declare @i int
set @i = 0
while @i < 100000
begin 
insert into testTran values (1,'Kin Shah')
set @i = @i+1
end
---------------------------------------------------
-- 2 sec
-- Implicit transaction
SET IMPLICIT_TRANSACTIONS ON
declare @i int
set @i = 0
while @i < 100000
begin 
insert into testTran values (1,'Kin Shah')
set @i = @i+1
end
COMMIT;
SET IMPLICIT_TRANSACTIONS OFF


----------------------------------------------------
-- 2 sec
-- Explicit transaction
declare @i int
set @i = 0
BEGIN TRAN
WHILE @i < 100000
Begin
INSERT INTO testTran values (1,'Kin Shah')
set @i = @i+1
End
COMMIT TRAN

Giao dịch tự động : (Được chỉnh sửa như được đánh dấu bởi @TravisGan)

  • Chèn mất 19 giây.
  • Mỗi Autocommit sẽ xóa bộ đệm T-log vào đĩa do autocomit (sau khi @TravisGan được tô sáng và tôi đã bỏ lỡ điều đó để đề cập).
  • Quá trình CHECKPOINT sẽ được hoàn thành nhanh chóng vì số lượng bộ đệm nhật ký bẩn cần phải được xóa sẽ ít hơn vì nó thường chạy yên tĩnh.

IMPLICIT & Giao dịch rõ ràng:

  • Chèn mất 2 giây.
  • Đối với giao dịch EXPLICIT, bộ đệm nhật ký sẽ chỉ bị xóa khi chúng đầy.
  • Trái ngược với giao dịch Autocommit, trong giao dịch EXPLICIT, quy trình CHECKPOINT sẽ mất nhiều thời gian hơn vì nó sẽ có nhiều bộ đệm nhật ký hơn để xóa (hãy nhớ rằng bộ đệm nhật ký chỉ được xóa khi chúng đầy).

Có một DMV sys.dm_tran_database_transilities sẽ trả về thông tin về Giao dịch ở cấp cơ sở dữ liệu.

Rõ ràng, đây là một loại thử nghiệm đơn giản hơn để chỉ ra tác động. Các yếu tố khác như hệ thống con đĩa, cài đặt tăng trưởng tự động cơ sở dữ liệu, kích thước ban đầu của cơ sở dữ liệu, các quy trình khác đang chạy trên cùng một máy chủ \ cơ sở dữ liệu, v.v. cũng sẽ có ảnh hưởng.

Từ các thử nghiệm trên, gần như không có sự khác biệt giữa các giao dịch Ngẫu nhiên & Rõ ràng.

Cảm ơn @TravisGan đã giúp thêm câu trả lời.


35

Một câu lệnh SQL luôn chạy trong một giao dịch. Nếu bạn không bắt đầu một cách rõ ràng, mọi câu lệnh SQL sẽ chạy trong một giao dịch của chính nó.

Sự lựa chọn duy nhất là liệu bạn có bó nhiều câu lệnh trong một giao dịch hay không. Các giao dịch trải rộng trên nhiều câu lệnh để lại các khóa gây tổn thương đồng thời. Vì vậy, "luôn luôn" tạo ra một giao dịch không phải là một ý tưởng tốt. Bạn nên cân đối chi phí so với lợi ích.


1

Vấn đề là liệu một nhóm các hoạt động phải được coi là một hành động duy nhất. Nói cách khác, tất cả các hoạt động phải được hoàn thành và cam kết thành công hoặc không có hoạt động nào có thể được cam kết. Nếu bạn có một kịch bản yêu cầu bạn đọc dữ liệu sơ bộ và sau đó thực hiện cập nhật dựa trên dữ liệu đó thì lần đọc đầu tiên có thể là một phần của giao dịch. Lưu ý: Tôi đang tránh Chọn / Chèn / Cập nhật trên mục đích. Phạm vi giao dịch thực sự có thể ở cấp ứng dụng và liên quan đến nhiều hoạt động của cơ sở dữ liệu. Hãy nghĩ về các mẫu kinh điển như Đặt chỗ ngồi trên máy bay hoặc Truy vấn / Rút tiền số dư ngân hàng. Người ta phải có cái nhìn rộng hơn về vấn đề để đảm bảo toàn bộ ứng dụng mang lại dữ liệu nhất quán, đáng tin cậy.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.