tôi đang chèn một bản ghi vào một bảng SQL Server và sau đó chọn ID auto-increment như sau:Tại sao Máy chủ SQL sau chèn khóa bế tắc khi chạy trong một giao dịch?
(@p0 int,@p1 nvarchar(8))INSERT INTO [dbo].[Tag]([Some_Int], [Tag])
VALUES (@p0, @p1)
SELECT CONVERT(Int,SCOPE_IDENTITY()) AS [value]
(Điều này đã được tạo ra sử dụng LINQ-to-SQL). Đối với một số lý do khi tôi chạy mã này bên trong một giao dịch bằng cách sử dụng đối tượng TransactionScope với một mức cô lập Serializable, SQL Server ném một lỗi bế tắc. Tôi đã phân tích các sự kiện bế tắc graph và thấy rằng hai quá trình liên quan đến mỗi người đều chờ đợi mặt khác để thực hiện các hoạt động chuyển đổi, như tôi hiểu được những thông tin sau:
<resource-list>
<keylock hobtid="72057594101170176" dbid="5" objectname="foo.dbo.Tag" indexname="PK_Tag_1" id="lockb77cdc0" mode="RangeS-S" associatedObjectId="72057594101170176">
<owner-list>
<owner id="processc9be40" mode="RangeS-S"/>
</owner-list>
<waiter-list>
<waiter id="processc9ae38" mode="RangeI-N" requestType="convert"/>
</waiter-list>
</keylock>
<keylock hobtid="72057594101170176" dbid="5" objectname="foo.dbo.Tag" indexname="PK_Tag_1" id="lockb77cdc0" mode="RangeS-S" associatedObjectId="72057594101170176">
<owner-list>
<owner id="processc9ae38" mode="RangeS-S"/>
</owner-list>
<waiter-list>
<waiter id="processc9be40" mode="RangeI-N" requestType="convert"/>
</waiter-list>
</keylock>
</resource-list>
sự hiểu biết của tôi là phạm vi giao dịch sẽ ngăn cản thứ hai quá trình thực hiện chèn cho đến khi người đầu tiên hoàn tất cả việc chèn và chọn danh tính. Tuy nhiên điều này dường như không đúng. Bất cứ ai có thể làm sáng tỏ một số cách tiếp cận tốt nhất để đạt được những gì tôi yêu cầu trong một cách an toàn thread?
- Cập nhật -
Chỉ cần lưu ý; Tôi chắc chắn rằng 99% kết nối không được chia sẻ giữa hai quy trình khi mỗi quá trình tạo một DataContext mới để giao tiếp với cơ sở dữ liệu.
- Cập nhật lần nữa -
Remus Rusanu chỉ ra rằng một số thông tin bỏ qua có liên quan đến vấn đề này, tôi đã cố gắng để đơn giản hóa các kịch bản dựa trên báo cáo bế tắc biểu đồ, nhưng tôi đã mở rộng giải thích đây. Trước khi tôi chèn, tôi thực hiện truy vấn tồn tại trên bảng được đề cập để xác định xem thẻ đã tồn tại hay chưa. Nếu tôi kết thúc giao dịch. Nếu không chèn nên đi trước và sau đó tôi thực hiện một bản cập nhật, không được hiển thị ở đây, trên một bảng có Some_Int
làm khóa chính, mặc dù bản cập nhật hoàn toàn là giá trị được sửa đổi lần cuối. Nó cũng có thể là quan trọng mà bảng Tag có một chỉ số nhóm bao gồm cả các tự động inc ID và Some_Int. Tôi không nghĩ rằng phần thông tin cuối cùng này có liên quan như tôi đã thử thay đổi bảng để chỉ có trường tự động inc là chỉ mục khóa/nhóm chính không có kết quả.
Cảm ơn.
Câu hỏi hay ho! Tôi muốn xem câu trả lời. – Chris