Manager classes and transactions

Posts   
 
    
wvnoort
User
Posts: 96
Joined: 06-Jan-2005
# Posted on: 24-Mar-2005 16:56:22   

I am using the adapter scenario and now want to create some manager classes that share the connections. The manager classes must be able to share the connections, since I want to call mutiple manager classes within a single connection. I have seen some uable examples on the forums on how to share the adapter. e.g. http://www.llblgen.com/tinyforum/Messages.aspx?ThreadID=2306

What i am curious about is, when do you create the adapter and when do you open and close the connection?

Let's say i have two classes UI1 and UI2 and four manager classes A, B, C and D. Pseudocode:


.. in some method of UI1 ...

A.Method1();
B.Method2();

.. in some method of UI2 ...

C.Method1();


// declarations manager classes
class A
{
    Public void Method1()
    {
        ...
        D.Methodx();
        ...
    }
}

class B
{
    Public void Method2()
    {
        ... implementation ...
    }
}

class C
{
    Public void Method1()
    {
        ...
        D.Methodx();
        ...
    }
}

class D
{
    Public void Methodx()
    {
        ... implementation ...
    }
}

At the moment i am tempted to say that the manager classes only participate in the transactions but may not be able to start or commit one. This will avoid unwanted side effects. One the other hand, I don't want to do anything with transactions in the PL. Does that mean that i have to create an extra (UI process) layer to solve this?

Thanks in advance, Wouter

jtgooding
User
Posts: 126
Joined: 26-Apr-2004
# Posted on: 24-Mar-2005 17:25:23   

Here is how I solved this issue, my UI calls the method without the adapter, and any sub call to either this manager or another manager calls it passing the existing adapter.

The save method then detects if an existing transaction is running and creates one if necessary, otherwise it creates a save point, each manager depending on if it started a transaction or a save point will only roll itself back, and lets the calling layer decide if it wants to cancel everything.


        public bool SaveRouteLocation()
        {
            return SaveRouteLocation(new DataAccessAdapter(_DefaultServer));
        }

        public bool SaveRouteLocation(DataAccessAdapter adapter)
        {
            bool bResult = false;
            int addressID = 0;
            bool bTransactionStarted = false;
            const string TransName = "SaveRouteLocation";

            try
            {
                if (IsSaveable)
                {
                    if (adapter.IsTransactionInProgress) 
                    {
                        adapter.SaveTransaction(TransName);
                    }
                    else
                    {
                        adapter.StartTransaction(IsolationLevel.ReadUncommitted, TransName);
                        bTransactionStarted = true;
                    }

                    try
                    {
                        if (_AddressManager.SaveAddress(adapter, out addressID))
                        {
                            _RouteLocation.AddressID = addressID;

                            if (adapter.SaveEntity(_RouteLocation))
                            {
                                bResult = true;
                            }
                        }
                    }
                    catch (ORMException ox)
                    {
                        ExceptionManager.Publish(ox);
                        bResult = false;
                    }
                    catch (Exception ex)
                    {
                        ExceptionManager.Publish(ex);
                        bResult = false;
                    }
                    finally
                    {
                        if (bResult)
                        {
                            if (bTransactionStarted)
                                adapter.Commit();
                        }
                        else
                        {
                            ExceptionManager.Publish("Unable to save new RouteLocation");
                            if (bTransactionStarted)
                                adapter.Rollback();
                            else
                                adapter.Rollback(TransName);
                        }
                    }
                }
                else
                    bResult = false;
            }
            catch (Exception ex)
            {
                ExceptionManager.Publish(ex);
                bResult = false;
            }
            return bResult;
        }