TransactionScope Timeout

TransactionScope Timeout

Old forum URL: forums.lhotka.net/forums/t/8540.aspx


Nemisis posted on Tuesday, February 16, 2010

Hi everyone,  I have some code that runs but it appears to timeout because of the transactionscope surrounding it.  Two questions.

1. Can i increase the timeout for that 1 dataportal call only?

2. My business logic is within the dataportal routine, where i retrieve objects, calculate some numbers etc and i add objects to the database.  The whole process must complete, that is why i have the transactionscope tag on the dataportal_execute method.  I dont really want the retrieves to be within the transaction, for performance reasons, so can i just put the save methods within a transaction?

e.g

Sub DataPortal_Execute() 

' Do some retrieves and calculations here

' Create a tranaction
' DO SAVES HERE?
End Sub 

Is this possible?

RockfordLhotka replied on Tuesday, February 16, 2010

Yes, switch to Manual transactions on your DP_Execute() method, and then manually create your own TransactionScope object in the method, only around the parts you want protected.

That should solve both problems.

Nemisis replied on Wednesday, February 17, 2010

Rocky,

Thanks, sorry to be a pain though, but how do i switch to manually transactions?  Do i simply leave out the transactionScope tag and then write the transaction code?  That what you mean?

Sorry if that sounds stupid 

Marjon1 replied on Wednesday, February 17, 2010

You'll change the attribute to be TransactionScope.Manual and then write the transaction code that is required for the whatever database you are using.

I was going to try and post an example, but still can't get the color formatting correct in my browser.

SethSpearman replied on Monday, December 01, 2014

Here is a sample of what is discussed in this post...

 

    <Transactional(TransactionalTypes.Manual)> _
    Protected Overrides Sub DataPortal_Execute()
        Dim options As TransactionOptions = New TransactionOptions() With {.IsolationLevel = IsolationLevel.ReadCommitted, .Timeout = TimeSpan.FromMinutes(4)}

        Using ts As New TransactionScope(TransactionScopeOption.Required, options)
                Using cn As New SqlConnection(Database.ApplicationConnection)
                    cn.Open()
                    Execute(cn)
            ts.Complete()
        End Using

    End Sub

rxelizondo replied on Wednesday, February 17, 2010

Nemisis

 how do i switch to manually transactions?  Do i simply leave out the transactionScope tag and then write the transaction code? 

 

Hi,

Manual transaction is achieved by either not decorating your DataPortal_Execute() function with the Transactional attribute or by decorating your function with the Transactional attribute but setting its value to manual as in: [Transactional(TransactionalTypes.Manual)]

once you have done any of the above you can then go ahead and do your transactions stuff just like you would do it anywhere else.

 

cmay replied on Wednesday, February 17, 2010

Also, I found that CSLA only look at the attribute on the DataPortal_X method.

I had tried having DataPortal_Update check something (like a config file) and if it was supposed to avoid transactions, to call another method like "UpdateWithoutTransactions", to which I applied the Manual transaction scope attribute, but CSLA doesn't walk up the calling stack to find the first transactionscope attribute, it just looks at the Dataportal_X method that instantiated everything.

rxelizondo replied on Wednesday, February 17, 2010

cmay

Also, I found that CSLA only look at the attribute on the DataPortal_X method.

 

That’s right, internally, when the DataPortal_XYZ is decorated with the transactional attribute that requires a transaction, the CSLA delegates the update code to a class called TransactionalDataPortal. Inside that class the update code looks like this:

--------------------------------------

public DataPortalResult Update(object obj, DataPortalContext context)
{
    DataPortalResult result;
    using (TransactionScope tr = new TransactionScope())
    {

        var portal = new DataPortalSelector();
        result = portal.Update(obj, context); // Calls your acutal implementation of your DataPortal_XYZ 
        tr.Complete();
    }
    return result;
}

--------------------------------------

Note how the portal.Update(obj, context) call (the code that ends up calling your acutal implementation of your DataPortal_XYZ ) is sorunded by the using (TransactionScope tr = new TransactionScope()).

So basically, anything running inside the DataPortal_XYZ will use the transaction scope.

Copyright (c) Marimer LLC