개발관련/오류노트

Entity Framework의 SqlException-세션에서 실행중인 다른 스레드가 있으므로 새 트랜잭션이 허용되지 않습니다.

Rateye 2021. 7. 5. 10:29
728x90
반응형

 

질문 : Entity Framework의 SqlException-세션에서 실행중인 다른 스레드가 있으므로 새 트랜잭션이 허용되지 않습니다.

현재이 오류가 발생합니다.

System.Data.SqlClient.SqlException : 세션에서 실행중인 다른 스레드가 있기 때문에 새 트랜잭션이 허용되지 않습니다.

이 코드를 실행하는 동안 :

public class ProductManager : IProductManager
{
    #region Declare Models
    private RivWorks.Model.Negotiation.RIV_Entities _dbRiv = RivWorks.Model.Stores.RivEntities(AppSettings.RivWorkEntities_connString);
    private RivWorks.Model.NegotiationAutos.RivFeedsEntities _dbFeed = RivWorks.Model.Stores.FeedEntities(AppSettings.FeedAutosEntities_connString);
    #endregion

    public IProduct GetProductById(Guid productId)
    {
        // Do a quick sync of the feeds...
        SyncFeeds();
        ...
        // get a product...
        ...
        return product;
    }

    private void SyncFeeds()
    {
        bool found = false;
        string feedSource = "AUTO";
        switch (feedSource) // companyFeedDetail.FeedSourceTable.ToUpper())
        {
            case "AUTO":
                var clientList = from a in _dbFeed.Client.Include("Auto") select a;
                foreach (RivWorks.Model.NegotiationAutos.Client client in clientList)
                {
                    var companyFeedDetailList = from a in _dbRiv.AutoNegotiationDetails where a.ClientID == client.ClientID select a;
                    foreach (RivWorks.Model.Negotiation.AutoNegotiationDetails companyFeedDetail in companyFeedDetailList)
                    {
                        if (companyFeedDetail.FeedSourceTable.ToUpper() == "AUTO")
                        {
                            var company = (from a in _dbRiv.Company.Include("Product") where a.CompanyId == companyFeedDetail.CompanyId select a).First();
                            foreach (RivWorks.Model.NegotiationAutos.Auto sourceProduct in client.Auto)
                            {
                                foreach (RivWorks.Model.Negotiation.Product targetProduct in company.Product)
                                {
                                    if (targetProduct.alternateProductID == sourceProduct.AutoID)
                                    {
                                        found = true;
                                        break;
                                    }
                                }
                                if (!found)
                                {
                                    var newProduct = new RivWorks.Model.Negotiation.Product();
                                    newProduct.alternateProductID = sourceProduct.AutoID;
                                    newProduct.isFromFeed = true;
                                    newProduct.isDeleted = false;
                                    newProduct.SKU = sourceProduct.StockNumber;
                                    company.Product.Add(newProduct);
                                }
                            }
                            _dbRiv.SaveChanges();  // ### THIS BREAKS ### //
                        }
                    }
                }
                break;
        }
    }
}

모델 # 1-이 모델은 Dev Server의 데이터베이스에 있습니다. 모델 # 1 http://content.screencast.com/users/Keith.Barrows/folders/Jing/media/bdb2b000-6e60-4af0-a7a1-2bb6b05d8bc1/Model1.png

모델 # 2-이 모델은 Prod Server의 데이터베이스에 있으며 자동 피드를 통해 매일 업데이트됩니다. 대체 텍스트 http://content.screencast.com/users/Keith.Barrows/folders/Jing/media/4260259f-bce6-43d5-9d2a-017bd9a980d4/Model2.png

참고-모델 # 1의 빨간색 원으로 표시된 항목은 모델 # 2에 "매핑"하는 데 사용하는 필드입니다. 모델 # 2의 빨간색 원은 무시하십시오.이 질문은 제가 가지고 있던 다른 질문에 대한 답변입니다.

참고 : 클라이언트의 인벤토리에서 사라진 경우 DB1에서 소프트 삭제할 수 있도록 isDeleted 확인을 입력해야합니다.

이 특정 코드를 사용하여 내가 원하는 것은 DB1의 회사를 DB2의 클라이언트와 연결하고 DB2에서 제품 목록을 가져와 아직없는 경우 DB1에 삽입하는 것입니다. 처음으로 전체 인벤토리를 가져와야합니다. 밤새 새 인벤토리가 피드에 들어오지 않는 한 아무 일도 일어나지 않은 후 실행될 때마다.

그래서 질문-내가 얻는 거래 오류를 어떻게 해결합니까? 루프를 통과 할 때마다 내 컨텍스트를 삭제하고 다시 만들어야합니까 (이치에 맞지 않음)?

답변

머리카락을 많이 뽑은 후 나는 foreach 루프가 범인이라는 것을 발견했습니다. 어떤 일이 필요로하는 것은 EF를 호출하지만,로를 반환하는 것입니다 IList<T> 그 대상 유형에서 다음 루프의 IList<T> .

예:

IList<Client> clientList = from a in _dbFeed.Client.Include("Auto") select a;
foreach (RivWorks.Model.NegotiationAutos.Client client in clientList)
{
   var companyFeedDetailList = from a in _dbRiv.AutoNegotiationDetails where a.ClientID == client.ClientID select a;
    // ...
}
출처 : https://stackoverflow.com/questions/2113498/sqlexception-from-entity-framework-new-transaction-is-not-allowed-because-ther
728x90
반응형