为什么我的代码被多次访问时会出现死锁
本文关键字:死锁 访问 我的 代码 为什么 | 更新日期: 2023-09-27 17:59:47
在我的c#代码中,我有以下方法在数据库中创建一个文档,将有关文档的元数据添加到数据库中,然后更新有关存储库上次更新日期的一些信息。由于多个文件上传很常见,因此这种方法经常被快速连续调用多次。然而,由于sql server中的死锁,我遇到了代码失败的问题。
private IEnumerable<DocumentMetadata> CreateDoc(int? jobId, int?repositoryId, int? folderId, string documentTypeString, IEnumerable<DocumentModel> files)
{
if ((jobId == null && repositoryId == null) || (jobId != null && repositoryId != null))
{
throw new InvalidOperationException("Either job id or repository id must be specified");
}
using (var tran = new TransactionScope())
{
List<DocumentMetadata> newDocuments = new List<DocumentMetadata>();
var documentType = GetDocumentTypeByPrefix(documentTypeString);
if (folderId == null)
{
// Find the root folder
var job = getJob(jobId);
var rootFolder = getRootFolder(job);
// If we can't find a root folder, create one
if (rootFolder == null)
{
rootFolder = CreateRootDirectory(job);
}
folderId = rootFolder.FolderId;
}
User currentUser = _userService.GetCurrentUser();
foreach (var file in files)
{
var document = new Document() { Document1 = file.Data };
var documentMetadata = new DocumentMetadata
{
Document = document,
CreatedDate = file.CreatedDate,
FileName = file.Filename,
FileSize = file.Data.Length,
FolderId = folderId,
DocumentType = documentType,
JobId = jobId,
RepositoryId = repositoryId,
User = currentUser
};
_unitOfWork.DocumentMetadata.Add(documentMetadata);
newDocuments.Add(documentMetadata);
}
// set repository updated date
if (repositoryId != null)
{
DocumentRepository repo = GetDocumentRepository(repositoryId);
if (repo != null)
{
repo.UpdatedDate = new DateTimeOffset(DateTime.Now);
}
}
_unitOfWork.SaveChanges();
tran.Complete();
return newDocuments;
}
}
经过一些调试后,存储库id的更新似乎导致了死锁问题。如果我在事务之外删除此代码块,则保存所有文件时不会出现错误。
为什么这个代码会阻止
if (repositoryId != null)
{
DocumentRepository repo = GetDocumentRepository(repositoryId);
if (repo != null)
{
repo.UpdatedDate = new DateTimeOffset(DateTime.Now);
}
}
造成僵局?除了在这个方法中之外,没有对DocumentRepository表进行其他访问——因为锁是按照相同的顺序获得的——当然不应该有死锁吗?
这段代码是怎么导致死锁的?
更新:GetDocumentRepository的代码为:
public DocumentRepository GetDocumentRepository(int repositoryId)
{
var result = DocumentRepositories.SingleOrDefault(x => x.RepositoryId == repositoryId); return result;
}
您是否在没有明确定义事务的情况下检查了代码?根据你的代码,我想说你正在尝试阅读一些经过修改但未提交的内容。您可以做的另一个测试是尝试在代码中添加断点,并尝试使用READ UNCOMITTED获取DocumentRepository。