Hiệu quả của việc có một giao dịch mở trong MSSQL quá lâu là gì?


11

Tôi chỉ tự hỏi điều gì sẽ xảy ra nếu bạn bắt đầu một giao dịch trong DB và quên cam kết hoặc khôi phục nó. Máy chủ sẽ ngừng hoạt động? Hãy nói rằng bạn đã để nó trong 3 ngày.

Cũng có những người dùng đang sử dụng nó giả định rằng những người dùng khác không biết rằng có một giao dịch không được tiết lộ (hãy giả sử rằng người dùng chỉ đang chèn dữ liệu vào cơ sở dữ liệu). Hậu quả của hành động này là gì?

Câu trả lời:


14

Có một giao dịch mở tự nó sẽ gần như không có kết quả. Một đơn giản

BEGIN TRANSACTION
-- wait for a while, doing nothing
-- wait a bit longer
COMMIT

tệ nhất là sẽ giữ một vài byte giá trị trạng thái. Không vấn đề gì.

Hầu hết các chương trình sẽ thực hiện công việc thực tế trong giao dịch và đây là một vấn đề khác. Điểm của một giao dịch là vì vậy bạn có thể chắc chắn rằng một số sự kiện trong cơ sở dữ liệu là đúng đồng thời, mặc dù có những người dùng khác viết vào cùng một cơ sở dữ liệu.

Lấy ví dụ điển hình về việc chuyển tiền giữa các tài khoản ngân hàng. Hệ thống phải đảm bảo rằng tài khoản nguồn tồn tại, có đủ tiền, tài khoản đích tồn tại và cả ghi nợ và tín dụng xảy ra hoặc không xảy ra. Nó phải đảm bảo điều này trong khi các giao dịch khác xảy ra, thậm chí có thể giữa hai tài khoản này. Hệ thống đảm bảo điều này bằng cách lấy các khóa trên các bảng liên quan. Những khóa nào được thực hiện và bao nhiêu công việc của những người khác mà bạn thấy, được kiểm soát bởi mức độ cô lập giao dịch .

Vì vậy, nếu bạn làm nhiều việc, rất có thể các giao dịch khác sẽ được xếp hàng chờ đợi các đối tượng mà bạn giữ khóa. Điều này sẽ làm giảm thông lượng chung của hệ thống. Cuối cùng, họ sẽ đạt đến giới hạn thời gian chờ và thất bại, đó là một vấn đề đối với hành vi hệ thống tổng thể. Nếu bạn sử dụng mức cô lập lạc quan, giao dịch của bạn có thể thất bại khi bạn thử cam kết vì công việc của người khác.

Giữ khóa mất tài nguyên hệ thống. Đây là bộ nhớ mà hệ thống không thể sử dụng để xử lý các yêu cầu khác, giảm thông lượng.

Nếu nhiều công việc đã được thực hiện, hệ thống có thể chọn thực hiện leo thang khóa . Thay vì khóa các hàng riêng lẻ, toàn bộ bảng sẽ bị khóa. Sau đó, nhiều người dùng đồng thời sẽ bị ảnh hưởng, thông lượng hệ thống sẽ giảm hơn nữa và tác động của ứng dụng sẽ lớn hơn.

Thay đổi dữ liệu được ghi vào tệp nhật ký, cũng như các khóa bảo vệ chúng. Chúng không thể bị xóa khỏi nhật ký cho đến khi giao dịch được thực hiện. Do đó giao dịch rất dài có thể gây ra sự phình to tệp nhật ký với các vấn đề liên quan của nó.

Nếu công việc hiện tại sử dụng tempdb, có khả năng cho khối lượng công việc lớn, tài nguyên ở đó có thể được gắn cho đến khi kết thúc giao dịch. Trong trường hợp cực đoan, điều này có thể khiến các nhiệm vụ khác thất bại vì không còn đủ chỗ cho chúng. Tôi đã gặp trường hợp một bản cập nhật được mã hóa kém điền tempdb do đó không còn đủ đĩa cho SORT của báo cáo và báo cáo không thành công.

Nếu bạn chọn ROLLBACK giao dịch, hoặc hệ thống bị lỗi và phục hồi, thời gian để hệ thống trở nên khả dụng một lần nữa sẽ phụ thuộc vào số lượng công việc được thực hiện. Đơn giản chỉ cần mở một giao dịch sẽ không ảnh hưởng đến thời gian phục hồi, đó là số lượng công việc đã được thực hiện. Nếu giao dịch được mở nhưng không hoạt động trong một giờ phục hồi sẽ gần như ngay lập tức. Nếu nó được viết liên tục trong giờ đó thì nguyên tắc chung là thời gian phục hồi cũng sẽ là khoảng một giờ.

Như bạn thấy giao dịch dài có thể có vấn đề. Đối với hệ thống OLTP, cách tốt nhất là có một giao dịch cơ sở dữ liệu cho mỗi giao dịch kinh doanh. Đối với đầu vào quy trình làm việc hàng loạt trong các khối, với các lần xác nhận thường xuyên và khởi động lại logic được mã hóa. Thông thường, vài nghìn bản ghi có thể được xử lý trong một giao dịch DB, nhưng điều này cần được kiểm tra để đồng thời và bán lại mức tiêu thụ.

Đừng bị cám dỗ để đi đến cực đoan khác và tránh hoàn toàn các giao dịch và khóa. Nếu bạn cần duy trì tính nhất quán trong dữ liệu của mình (và tại sao bạn lại sử dụng cơ sở dữ liệu?) Thì mức độ cô lập và giao dịch phục vụ một mục đích rất quan trọng. Tìm hiểu về các lựa chọn của bạn và quyết định số dư đồng thời và tính chính xác mà bạn đã chuẩn bị để sống với từng phần trong ứng dụng của mình.


ngay cả khi nó được mở trong ba ngày?
JanLeeYu

Vâng, thậm chí trong ba ngày. Điểm quan trọng là khối lượng công việc đã được thực hiện trong khi TX mở, không chỉ là nó đã được mở trong bao lâu. Tất nhiên, là một DBA, bạn có thể muốn hỏi chủ sở hữu giao dịch tại sao họ cần mở nó quá lâu. Khi tôi điều hành một nhóm DBA, tôi đã đăng nhập tất cả TX đã mở hơn 30 phút và có một cuộc trò chuyện với chủ sở hữu.
Michael Green

ĐỒNG Ý. Cảm ơn lời giải thích tuyệt vời. Mặc dù mọi người cũng đã làm rất tốt.
JanLeeYu

Thật là nhẹ nhõm ... Cảm ơn một lần nữa cho câu trả lời.
JanLeeYu

"CẬP NHẬT kém" Yup. Xem cái này đi. Một tuyên bố cập nhật bên trong một vòng lặp không đủ điều kiện một số tên và dẫn đến hành vi 1 = 1, do đó, nó đã cập nhật toàn bộ bảng cho mỗi lần lặp của vòng lặp (cũng đưa dữ liệu sai vào hầu hết các hàng đó).
jpmc26

6

Hậu quả lớn nhất của bạn sẽ là chặn các đối tượng được sử dụng trong giao dịch. Đặc biệt nếu bạn cho rằng người dùng của bạn đang chèn dữ liệu, thì giao dịch chạy dài đó có thể bao gồm các câu lệnh CHỌN trên các bảng thường được sử dụng. Báo cáo cập nhật của người dùng của bạn có thể không có được khóa cần thiết để hoàn thành các cập nhật hoặc chèn của họ.

Một điều thứ hai có thể xảy ra là hoạt động tệp nhật ký, giả sử nếu bạn đang cập nhật một tập dữ liệu lớn, phần nhật ký mà giao dịch đang sử dụng được giữ hoạt động trong suốt thời gian của giao dịch đó. Bạn sẽ không thể sử dụng lại phần đó của nhật ký cho đến khi giao dịch được cam kết hoặc khôi phục. Trong trường hợp bạn có thể ở trong một hệ thống OLTP hoạt động mạnh, điều này có thể khiến tệp nhật ký của bạn phát triển nhanh chóng, làm đầy thiết bị lưu trữ của bạn.


ví dụ người tạo giao dịch bị ngắt kết nối với máy chủ, anh ấy / cô ấy có thể đăng nhập lại vào máy chủ để đóng giao dịch không?
JanLeeYu

Nó sẽ phụ thuộc, nếu giao dịch trong môi trường sử dụng MSDTC, đó có thể là giao dịch mồ côi. Trong trường hợp đó, không người dùng nào không còn có thể tự đóng nó ... DBA sẽ phải bước vào để xử lý nó. Ngoài ra, thông thường bạn sẽ thấy giao dịch bị hủy bởi SQL Server khi nó ngắt kết nối ... nhưng một lần nữa đối với các giao dịch lớn có thể không xảy ra mọi lúc.

Trong trường hợp điều đó xảy ra, quản trị viên vẫn có thể đóng giao dịch phải không?
JanLeeYu

Tôi không thể trả lời rằng, tất cả phụ thuộc. Tôi đã có trường hợp máy chủ phải được khởi động lại, hoặc trường hợp thất bại đối với nút / bản sao thứ cấp.

4

Giao dịch không đầy đủ có thể giữ số lượng lớn các khóa và gây ra chặn

Khi giao dịch không được hoàn thành vì hết thời gian truy vấn hoặc do lô bị hủy giữa giao dịch mà không đưa ra câu lệnh CAMIT hoặc ROLLBACK để hoàn tất giao dịch, giao dịch sẽ bị mở và tất cả các khóa có được trong quá trình giao dịch đó tiếp tục được tổ chức. Các giao dịch tiếp theo được thực hiện trong cùng một kết nối được coi là giao dịch lồng nhau, vì vậy tất cả các khóa có được trong các giao dịch đã hoàn thành này không được phát hành. Vấn đề này lặp lại với tất cả các giao dịch được thực hiện từ cùng một kết nối cho đến khi ROLLBACK được thực thi. Do đó, một số lượng lớn các khóa được giữ, người dùng bị chặn và giao dịch bị mất, dẫn đến dữ liệu khác với những gì bạn mong đợi.

nguồn


ví dụ người tạo giao dịch bị ngắt kết nối với máy chủ, anh ấy / cô ấy có thể đăng nhập lại vào máy chủ để đóng giao dịch không?
JanLeeYu

Khi SQL Server biết kết nối bị mất, nó sẽ khôi phục giao dịch. Xem tại đây dba.stackexchange.com/questions/47404/ . Nếu cùng một người dùng kết nối lại, đó sẽ là một phiên khác vì vậy bằng cách nào đó không thể "chấp nhận" giao dịch cũ.
Michael Green
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.