Khi chính xác nhiều người dùng không thể đồng thời chạy một thủ tục được lưu trữ với bảng tạm thời?


9

Tôi có một câu hỏi liên quan đến một phần tài liệu về Bàn Temp mà tôi mới đọc trên TechNet . Đoạn thứ tư của phần Bảng tạm thời trên trang đó có nội dung như sau:

Nếu một bảng tạm thời được tạo với một ràng buộc được đặt tên và bảng tạm thời được tạo trong phạm vi giao dịch do người dùng xác định, chỉ một người dùng tại một thời điểm có thể thực hiện câu lệnh tạo bảng tạm thời. Ví dụ: nếu một thủ tục được lưu trữ tạo một bảng tạm thời với ràng buộc khóa chính được đặt tên, thì thủ tục được lưu trữ có thể được thực thi đồng thời bởi nhiều người dùng.

Tôi làm việc trong một môi trường nơi chúng tôi sử dụng đáng kể một số thủ tục được lưu trữ sử dụng các bảng tạm thời được lập chỉ mục và chúng tôi chưa bao giờ gặp phải vấn đề mà người dùng phải chờ một lần thực hiện trước khi bắt đầu tiếp theo. Tôi hy vọng điều đó sẽ tiếp tục là trường hợp, nhưng tôi lo ngại rằng nó có thể trở thành một vấn đề nếu cảnh báo này không được hiểu đúng.

Cụ thể, tôi không rõ ràng về các điểm sau:

  1. Điều này chỉ áp dụng cho các bảng tạm thời toàn cầu, hoặc cho các bảng địa phương là tốt? Có vẻ lạ khi một bảng không hiển thị bên ngoài phiên (như trong trường hợp sau) sẽ ngăn phiên khác thực thi đồng thời.
  2. Những gì đủ điều kiện là một "ràng buộc được đặt tên"? Không phải tất cả các ràng buộc đều có tên (ngay cả khi chúng được tạo bởi hệ thống)? Đây có phải là đề cập đến các ràng buộc với bí danh do người dùng định nghĩa không? Điều này có vẻ như phrasing nghèo đối với tôi.
  3. "Nhiều người dùng" thực sự có nghĩa là nhiều phiên? Các quy trình này được gọi thông qua ứng dụng của chúng tôi bằng một tài khoản dịch vụ duy nhất, vì vậy 99,9% các cuộc gọi đến tập lệnh của chúng tôi được thực hiện với DB bằng tài khoản đó (và tôi không quan tâm đến việc gọi quản trị viên thỉnh thoảng có thể thực hiện trong phần phụ trợ). Nếu tài khoản dịch vụ có thể chạy sproc trong nhiều phiên cùng một lúc, thì vấn đề này sẽ được khắc phục cho mục đích của tôi.

1
Bạn đề cập rằng các bảng tạm thời của bạn được lập chỉ mục nhưng câu hỏi là về các chống chỉ định. Các chỉ mục không bị ràng buộc. Điều gì đúng với người này có thể đúng hoặc không đúng với người kia. Trong trường hợp này, tên chỉ mục có thể được sao chép trong cơ sở dữ liệu, không giống như các ràng buộc. Tên chỉ mục không thể được nhân đôi trên một bảng. Vì vậy, các chỉ mục được đặt tên sẽ không gây ra các vấn đề được đặt tên sẽ ràng buộc.
Shannon Severance

@Shannon, thực sự, tại thời điểm tôi viết câu hỏi, tôi đã nhầm lẫn điểm này. Tôi nghĩ rằng việc sử dụng chủ yếu của PRIMARY KEY CLUSTERED so với PRIMary KEY mà tôi đã thấy trong mã mẫu và tài liệu đã khiến tôi tin rằng các chỉ mục được nhóm là các ràng buộc. Và, bằng cách mở rộng, để suy ra rằng tất cả các chỉ mục là các ràng buộc. Tôi đã đọc một số buổi chiều nhẹ trước đó đã xóa điều này cho tôi.
Wesley Marshall

Câu trả lời:


10

Tôi nghĩ về nó vì bạn không thể có bất kỳ tên trùng lặp nào tempdb.sys.key_constraints. Đây là những gì trong chế độ xem siêu dữ liệu đó trên một trong các máy chủ của tôi:

cái nhìn ban đầu

Tất cả các tên lẻ kết thúc bằng các _6E...tên được tạo tự động bởi SQL Server. Chúng không được đặt tên ràng buộc vì tôi không đặt tên rõ ràng cho chúng khi tạo chúng. SQL Server tạo ra một tên ràng buộc đằng sau hậu trường mà theo lý thuyết sẽ tránh được sự va chạm tên.

Nếu tôi cố gắng tạo bảng sau trong hai phiên khác nhau:

create table #x1 (
ID INT NOT NULL,
CONSTRAINT NAMED_CONSTRAINT_1 PRIMARY KEY (ID)
);

Cái chạy thứ hai sẽ gây ra lỗi:

Msg 2714, Cấp 16, Bang 5, Dòng 1

Đã có một đối tượng có tên 'NAMED_CONSTRAINT_1' trong cơ sở dữ liệu.

Msg 1750, Cấp 16, Bang 1, Dòng 1

Không thể tạo ràng buộc hoặc chỉ mục. Xem các lỗi trước.

Kiểm tra xem lại:

với sự ràng buộc

Nếu tôi cố gắng tạo bảng sau trong hai phiên thì không có vấn đề gì:

create table #y1 (
ID INT NOT NULL,
PRIMARY KEY (ID)
);

Đây là chế độ xem siêu dữ liệu:

với các ràng buộc mặc định

Chỉ cần trả lời trực tiếp câu hỏi của bạn: phần mà bạn trích dẫn áp dụng cho cả bảng tạm thời cục bộ và toàn cầu, một ràng buộc được đặt tên là một trong đó bạn cố tình đặt tên cho nó và nhiều người dùng có nghĩa là nhiều phiên.


11

Điều này áp dụng cho các bảng tạm thời địa phương.

Sự khác biệt giữa các ràng buộc được đặt tên và không được đặt tên là:

CREATE TABLE #t1 (c1 INT PRIMARY KEY CLUSTERED)

CREATE TABLE #t2 (c1 INT,
                     CONSTRAINT pk_c1 PRIMARY KEY  CLUSTERED(c1) )

Để các ràng buộc tên hệ thống làm cho nó cực kỳ khó xảy ra xung đột. Trong ví dụ này, nếu bạn mở hai cửa sổ trong SSMS, bạn sẽ có thể tạo #t1cả hai, nhưng không #t2.

Các bảng tạm thời toàn cầu được chia sẻ bởi tất cả người dùng, vì vậy bạn phải xử lý mọi thứ khác nhau. Họ không bị "hủy" cho đến khi phiên cuối cùng được thực hiện bằng cách sử dụng chúng, vì vậy bạn cần đảm bảo rằng khi người dùng truy cập vào họ, họ chỉ có thể truy cập dữ liệu của họ. Điều này đôi khi được thực hiện bởi SPID, lần khác bằng giá trị băm. Nó phụ thuộc vào cách sử dụng bảng tạm thời toàn cầu.

Thông thường đối với các bảng tạm thời toàn cầu, các quy trình được lưu trữ sẽ kiểm tra xem chúng có tồn tại không, và sau đó chỉ tạo chúng nếu OBJECT_ID()NULL.

Nhiều người dùng có nghĩa là nhiều phiên. Tên đăng nhập không có gì để làm với nó. Nếu George chạy sp_something @i = 1và Gina chạy sp_something @i = 2, sẽ không có vấn đề gì nếu cả hai đều đăng nhập User1, họ sẽ có SPID khác nhau.

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.