The EntitySpaces Community

Share and learn about the EntitySpaces Architecture.
Welcome to The EntitySpaces Community Sign in | Join | Help
in
Home Forums Photos

Using esTransactionScope

Last post 04-12-2007, 9:23 AM by rareDevGuy. 9 replies.
Sort Posts: Previous Next
  •  01-29-2007, 4:16 AM 57

    Using esTransactionScope

    This example uses the EntitySpaces esTransactionScope class to save two EntitySpaces objects in a transaction. The esTransactionScope is used just like the .NET TransactionScope class only it is not distributed and works at the connection level.

     

    Code:
    Employees emp = new Employees (); 
    emp.FirstName = "Mike"; 
    emp.LastName = "Entity"; 
    
    using(esTransactionScope scope = new esTransactionScope()) 
    { 
        emp.Save(); 
    
        Dependent dep = new Dependent (); 
        dep.EmployeeID = emp.EmployeeID; 
        dep.FirstName = "Jr"; 
        dep.LastName = "Entity"; 
        dep.Save(); 
    }

    Of course, when you call Save and are using our Hierarchical Model then you don't have to explicitly create a transaction. The only time you should ever declare a transaction is when you need to save two objects that are unrelated or not in the hierarchical model. 


    EntitySpaces | Twitter | BLOG | Please honor our Software License
    Filed under:
  •  04-11-2007, 7:34 AM 1716 in reply to 57

    Re: Using esTransactionScope

    I am using ES and VistaDB to do an Hierarchical save.  According to the forum - http://www.vistadb.net/forums/viewtopic.php?t=1285&highlight=transaction - Vista requires you to manually rollback a transaction.  It seems that these transactions are getting 'stuck' when I break out of the debugger during the save.  I am getting a concurency error - see below.

     Here is my code to save the item back to the DB:

    Code:
                    //save the employee to the local DB
                        employee.EndEdit();
    
                        if (employee.Collection != null)
                        {
                            employee.Collection.Save();
                        }
                        else
                        {
                            employee.Save();
                        }

     

    and here is the error I am getting:

    Code:
    1    VistaDB.Diagnostic.VistaDBException was unhandled
    2      Message="\r\nError 455: Concurrency error. The row is being updated or deleted by another active transaction \r\nError 251: Cannot update row:  \nTable: 'Employee', RowId = 170\n\r\n"
    3      Source="EntitySpaces.Core"
    4      ErrorId=251
    5      LevelMessage="Error 251: Cannot update row:  \nTable: 'Employee', RowId = 170"
    6      StackTrace:
    7           at EntitySpaces.Core.esEntityCollection.SaveToProviderInsertsUpdates(esSqlAccessType sqlAccessType)
    8           at EntitySpaces.Core.esEntityCollection.SaveToProvider(esSqlAccessType sqlAccessType)
    9           at EntitySpaces.Core.esEntityCollection.Save(esSqlAccessType sqlAccessType)
    10          at EntitySpaces.Core.esEntityCollection.Save()
    11          at rhi.EmployeeEntry.EmployeeManagement.AddEditEmployeeViewPresenter.OnSubmitEmployee_Click() in C:\Projects\EmployeeEntry.root\!EmployeeEntryClient\Source\EmployeeManagement\EmployeeManagement.Module\Views\AddEditEmployeeViewPresenter.cs:line 398
    12          at rhi.EmployeeEntry.EmployeeManagement.AddEditEmployeeView.btnSaveAndSubmit_Click(Object sender, EventArgs e) in C:\Projects\EmployeeEntry.root\!EmployeeEntryClient\Source\EmployeeManagement\EmployeeManagement.Module\Views\AddEditEmployeeView.cs:line 142
    13          at System.Windows.Forms.Control.OnClick(EventArgs e)
    14          at System.Windows.Forms.Button.OnClick(EventArgs e)
    15          at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
    16          at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
    17          at System.Windows.Forms.Control.WndProc(Message& m)
    18          at System.Windows.Forms.ButtonBase.WndProc(Message& m)
    19          at System.Windows.Forms.Button.WndProc(Message& m)
    20          at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
    21          at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
    22          at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
    23          at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
    24          at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
    25          at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
    26          at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
    27          at System.Windows.Forms.Application.Run(Form mainForm)
    28          at Microsoft.Practices.CompositeUI.WinForms.FormShellApplication`2.Start()
    29          at Microsoft.Practices.CompositeUI.CabApplication`1.Run()
    30          at rhi.EmployeeEntry.Infrastructure.Shell.ShellApplication.RunInDebugMode() in C:\Projects\EmployeeEntry.root\!EmployeeEntryClient\Source\Infrastructure\Shell\ShellApplication.cs:line 56
    31          at rhi.EmployeeEntry.Infrastructure.Shell.ShellApplication.Main() in C:\Projects\EmployeeEntry.root\!EmployeeEntryClient\Source\Infrastructure\Shell\ShellApplication.cs:line 47
    32          at System.AppDomain.nExecuteAssembly(Assembly assembly, String[] args)
    33          at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
    34          at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
    35          at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
    36          at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
    37          at System.Threading.ThreadHelper.ThreadStart()
    38   
    
  •  04-11-2007, 7:54 AM 1717 in reply to 1716

    Re: Using esTransactionScope

    EntitySpaces always does a rollback or commit, that is why we use the "using" syntax, my guess is that the debugger is just "killing" the process or something. Also, we have found no bugs in ES relating to VistaDB, however, we have found many bugs in VistaDB. That is not to say we do not like VistaDB, I think it has great potential and is far superior to SQL CE by a mile.


    That being said, do you have Timestamp columns in your tables, that is the only way I can see you getting a concurrency error?  I tend to stop my application rather than press "Stop  Debugging" in Visual Studio for this very reason.

     

    If this only happens when you stop the debugger I can see where this might be annoying but don't really think this is an EntitySpaces "thing" ? However, we are here to help.
     


    EntitySpaces | Twitter | BLOG | Please honor our Software License
  •  04-11-2007, 7:58 AM 1718 in reply to 1717

    Re: Using esTransactionScope

    No there are no timestamp columns in my tables.  Is there ANY way to figure out exactly what 'command' is throwing the Vista DB error.  I need someway to see the exact query that's being passed in to vista.  There doesn't seem to be anything similar to SQL Query Analyzer or process monitor, etc. like SQL 2005 has.

    Any help would be greatly appreciated - this is driving me crazy!

  •  04-11-2007, 8:02 AM 1719 in reply to 1718

    Re: Using esTransactionScope

    Does it only occur if you stop the debugger? Also, are you running with their connection pooling turned on?

    EntitySpaces | Twitter | BLOG | Please honor our Software License
  •  04-11-2007, 8:39 AM 1720 in reply to 1719

    Re: Using esTransactionScope

    No, it occurs whether I stop the debugger or not.  It also occurs in the runtime.
    How would I know if I am using connection pooling - where is that setting?

  •  04-11-2007, 8:47 AM 1722 in reply to 1720

    Re: Using esTransactionScope

    Do me a favor and post more of the code (the stuff above your original post)

    EntitySpaces | Twitter | BLOG | Please honor our Software License
  •  04-11-2007, 9:09 AM 1723 in reply to 1722

    Re: Using esTransactionScope

    Here is the entier 'SAVE' method which occurs when the SAVE AND SUBMIT button is clicked.  Other than that, I basically have a three-part tab page; each with employee details on it.  I have a related child table called "EmployeeStatusChange" which keeps up with the 'status' of each employee (hired, fired, loa, etc).  Basically, I am trying to add a new record to this table each time.  I can give you some of that code, if it is helpful.

    Code:
    1    internal void OnSubmitEmployee_Click()
    2            {
    3                //validate entire form before allowing the save
    4                if (_employeeDetailView.ValidateForSave(false) && _employeeJobcodeView.ValidateForSave() && _employeeZapView.ValidateForSave())
    5                {
    6                    //set the employee's status, if not set, or if status is DRAFT or RECOVERED
    7                    if (employee.EmployeeStatusID == null || employee.EmployeeStatusID == EmployeeStatus.DRAFT || employee.EmployeeStatusID == EmployeeStatus.RECOVERED)
    8                        employee.EmployeeStatusID = EmployeeStatus.ACTIVE;
    9    
    10                   //set the employee's primary jobcode, if available
    11                   if (employee.EmployeeJobCodeCollectionByEmployeeID.Count > 0)
    12                       employee.PrimaryJobCodeID = ((EmployeeJobCode)employee.EmployeeJobCodeCollectionByEmployeeID[0]).JobCodeAloha;
    13   
    14                   //set the create and/or updated time
    15                   employee.CreatedDate = employee.CreatedDate ?? DateTime.Now;
    16                   employee.LastModifiedDate = DateTime.Now;
    17   
    18                   //set the employee's hire date, if not already set
    19                   employee.HireDate = employee.HireDate ?? employee.AlohaStartDate;
    20   
    21                   //save the employee to the local DB
    22                   employee.EndEdit();
    23   
    24                   if (employee.Collection != null)
    25                   {
    26                       employee.Collection.Save();
    27                   }
    28                   else
    29                   {
    30                       employee.Save();
    31                   }
    32   
    33                   string msg = string.Empty;
    34                   msg += "Saving employee to local database ... successful.\n";
    35                    msg += "Employee " + employee.ToString() + " has been created.";
    36                   this.shellNotificationService.Show(msg, "Creating New Employee");
    37   
    38                   //close the view
    39                   this.OnCloseView();
    40               }
    41   
    42           }
    
  •  04-12-2007, 6:50 AM 1751 in reply to 1716

    Re: Using esTransactionScope

    Have you seen this thread on the VistaDB forums?

    http://www.vistadb.net/forums/viewtopic.php?t=1473

    EntitySpaces | Twitter | BLOG | Please honor our Software License
  •  04-12-2007, 9:23 AM 1759 in reply to 1751

    Re: Using esTransactionScope

    Yes, but it wasn't very helpful.  Acutally, I solved the problem by reviewing my LastEmployeeStatusChange property of my Employee object.  What was happening, is that I was adding a new object (employee.statusChangeCollection.AddNew()) if one didn't exist.  The problem is that no properties were being set on that object, so it was throwing errors when trying to write to the database.  To solve this, I implemented a function that only added the 'statusChange' object to the collection if and when the variables were set.  This seemed to fix the problem - I hope it really did!  Huh?

    Code:
                //add the LastEmployeeStatusChange to the EmployeeStatusChangeCollectionByEmployeeID, if needed
                if (employee.LastEmployeeStatusChange.EmployeeID == null)
                {
                    employee.LastEmployeeStatusChange = employee.EmployeeStatusChangeCollectionByEmployeeID.AddNew();
                    chkIsTerminated.Enabled = false;
                    bool holdChecked = chkIsTerminated.Checked;
    
                   //call setLookupBindingDatasources() to rebind the "LastEmployeeStatusChange" object
                    setLookupBindingDatasources();
                    chkIsTerminated.Enabled = true;
                    chkIsTerminated.Checked = holdChecked;
                    return;
                }
    
View as RSS news feed in XML