0

I have created Generic Repository and I have two entities that i need to update in a transaction. Here is what i m doing..

ProductOrganizationEntity poDataContext= new ProductOrganizationEntity();
IRepository<tblProductInfo> productRepo = new GenericRepository<ProductOrganizationEntity, tblConfirmation>(poDataContext);

Piece of Code which is causing problem is this.

 using (TransactionScope txScope = new TransactionScope())
 {
                    productRepo.Attach(productEntity);
                    productRepo.SaveChanges();
                    new ProductLocation().SaveLocation(productEntity.Locations, productEntity.productCode);
                    txScope.Complete();
 }

productRepo.SaveChanges(); This is where it throws me Error. The error is

The operation could not be performed because OLE DB provider "SQLNCLI10" for linked server "Venus" was unable to begin a distributed transaction.

(We do have server named Venus but its not access in anyway in these transactions at all. Secondly as i said this works without transaction block).

This piece of code works fine if taken out from Transaction Block.

ProductLocation.SaveLocation is creating Repository for Location . Here is the code from Save Location.

IRepository<LocationInfo> locRepo= new GenericRepository<ProductOrganizationEntity, LocationInfo>(new ProductOrganizationEntity());

 if (loc.locID <= 0) // This is a new Location to be added.
      locRepo.Add(locEntity);
 else
     locRepo.Attach(siteToAdd);

 locRepo.SaveChanges();

Here is what i have done in my generic repository for thse methods

   public void Attach(TEntity entity)
    {
        if (entity == null)
            throw new ArgumentException("Update : Supplied Entity is Null.");

        _currentDbSet.Add(entity);
        System.Data.Entity.Infrastructure.DbEntityEntry entry = _dataContext.Entry(entity);
        entry.State = System.Data.EntityState.Modified;
    }

and this is what i have in SaveChanges in my generic repo.

 public virtual void SaveChanges()
    {
        if (_dataContext == null)
            throw new Exception("SaveChanges: DataContext is not initialized.");

        _dataContext.SaveChanges();
    }

What is that i am doing wrong here .

I appreciate any pointers.

Tabish Sarwar
  • 1,505
  • 1
  • 11
  • 18
  • Do you need to do this in a single transaction scope? Can you create the ProductLocation, and attach the productEntity, then save changes? This should prevent your system from needing the DTC, which is the source of your error. – Mark Oreta Sep 06 '12 at 18:59
  • I honestly dont understand why DTC is being issued here. This code works fine as it is without TransactionScope . the INSERT piece works fine in TransactionScope. However i didnt exactly got what you mean by Can you create the ProductLocation, and attach the productEntity, then save changes? thx – Tabish Sarwar Sep 06 '12 at 19:18
  • What is your ProductLocation().SaveLocation() code actually doing? See [this post](http://stackoverflow.com/questions/1690892/transactionscope-automatically-escalating-to-msdtc-on-some-machines) as to why the DTC gets called up. – Mark Oreta Sep 06 '12 at 19:21
  • ProductLocation().SaveLocation() is not even being called . It crashed with the Error when i am calling productRepo.SaveChanges(); I verified that with removing everything related to Location from TransactionBlock and still it throws error. Does it has to do something with my code in my repository for Attach ? – Tabish Sarwar Sep 06 '12 at 19:29
  • Probably - The _dataContext.Entry(entity) *may* be making a DB call, but honestly I'm not really sure. Either way, the DTC would definitely be called up with your next line of code, since it's calling a new repo, and trying to open a new connection. If you aren't able to enable DTC on the servers (and it sounds like you cant) you won't be able to do this in a single scope. Why do you need this all in single scope? Are you worried about race conditions? You could do something like a unit of work pattern, where all your repos would share a context, then you could call a single save changes. – Mark Oreta Sep 06 '12 at 19:52

1 Answers1

1

It might be possible that your server is linked to another SQL server at the database level.

Perhaps look at this: http://msdn.microsoft.com/en-us/library/ms188279.aspx

Must admit I've never used linked servers (not yet at least), but seeing "Linked Servers" in the error made me think of this.

Alex KeySmith
  • 16,657
  • 11
  • 74
  • 152
  • I m not sure about it becasue . The INSERT works fine within the transaction scope . and this UPDATE code works fine when TransactionScope is taken out . The only problem is as soon as this is put in TransactionScope. I get that error. – Tabish Sarwar Sep 06 '12 at 19:13
  • Hi @TabishSarwar how did you fix it in the end? – Alex KeySmith Sep 24 '12 at 08:13
  • Alex, There was an undocumented trigger by some other developer and was not being used ever . That trigger was trying to select something from another Linked server and doing some update. All i had to do was take that trigger out and it worked . There was no problem technically on what i was doing. – Tabish Sarwar Sep 24 '12 at 14:07
  • Cool, glad you got to the bottom of it. That must of been a tricky one to spot. – Alex KeySmith Sep 24 '12 at 15:20