Tôi có một bảng có cột nhận dạng và tôi muốn dự trữ một khối id mà tôi có thể sử dụng để chèn số lượng lớn, trong khi cho phép chèn vẫn xảy ra trong bảng đó.
Lưu ý đây là một phần của một số lượng lớn một số bảng, trong đó các bảng khác liên quan đến các id này thông qua FK. Vì vậy, tôi cần phải chặn chúng để tôi có thể chuẩn bị các mối quan hệ trước.
Tôi đã tìm thấy một giải pháp hoạt động bằng cách khóa trên bàn trong một giao dịch và sau đó thực hiện lại (điều này khá nhanh). Nhưng nó có vẻ hơi khó hiểu đối với tôi - có một mô hình thường được chấp nhận để làm điều này không?
create table dbo.test
(
id bigint not null primary key identity(1,1),
SomeColumn nvarchar(100) not null
)
Đây là mã để chặn (nhường chỗ cho) một số id:
declare @numRowsToMakeRoomFor int = 100
BEGIN TRANSACTION;
SELECT MAX(Id) FROM dbo.test WITH ( XLOCK, TABLOCK ) -- will exclusively lock the table whilst this tran is in progress,
--another instance of this query will not be able to pass this line until this instance commits
--get the next id in the block to reserve
DECLARE @firstId BIGINT = (SELECT IDENT_CURRENT( 'dbo.test' ) +1);
--calculate the block range
DECLARE @lastId BIGINT = @firstId + (@numRowsToMakeRoomFor -1);
--reseed the table
DBCC CHECKIDENT ('dbo.test',RESEED, @lastId);
COMMIT TRANSACTION;
select @firstId;
Mã của tôi là khối xử lý hàng loạt dữ liệu trong khối khoảng 1000. Tôi có khoảng một tỷ hàng để chèn tổng cộng. Mọi thứ đều hoạt động tốt - cơ sở dữ liệu không phải là cổ chai, việc xử lý hàng loạt rất tốn kém về mặt tính toán và yêu cầu tôi phải thêm một vài máy chủ để chạy song song, vì vậy tôi cần điều chỉnh nhiều hơn một quy trình "chèn hàng loạt" tại cùng một lúc
INSERT .. SELECT ..
vớiOUTPUT
? Không khóa, không gieo hạt. Chỉ cần XÁC NHẬN và nhận ID từ OUTPUT để bạn có thể sử dụng chúng trong các bảng khác.