Easily overlooked but serious concurrency bug

Print Topic | Close Window

By Sam Tenney - 12/15/2010 6:26:39 AM
I have spent many hours stepping through StrataFrame source code and I have discovered a bug that under very simple but specific circumstances causes a record in the local internal data table to be incorrectly deleted immediately after the original record in the backend database table was not deleted because of a legitimate concurrency conflict.  This occurs with no warning message displayed but leaves the data in the local internal data table showing that the record has been deleted, but the backend database table showing that the record was NOT deleted.

The bug occurs in unmodified StrataFrame source code when attempting to delete a record from a very simple StrataFrame maintenance form with the business object's DeleteConcurrencyType property set to OptimisticRowVersion and the RowVersionOrTimestampColumn property set to the name of the database table's rowversion column.  All other properties in every related object remain set to StrataFrame default values.

I want to find someone willing to spend a few minutes duplicating this problem.  Unfortunately based on my previous experience on and off this forum, it will probably be very difficult to convince anyone that a bug exists in StrataFrame source code that has been in use for years.  I understand why most people will feel that way, but this bug shows up when using only unmodified StrataFrame source code and by simply trying to delete one single record at a time.  I just need someone willing to duplicate the bug using their own database application that uses a rowversion column in the backend database table.

I think I even know where in the StrataFrame source code the problem exists, but I do not have enough experience to rewrite the incorrect source code.

Any takers?

Sam Tenney
By Keith Chisarik - 12/15/2010 7:22:46 AM
Maybe you can post a sample project against the SF sample database that reproduces the issue and then the specific steps to reproduce?
By Sam Tenney - 12/15/2010 10:00:59 AM
Attached is a ConcurrencyBugSample solution that demonstrates the bug.  The solution uses the SF Sample Database and the Customers table.  I intentionally created this very basic solution with no whistles and bells.  It is not pretty, but it demonstrates the bug.  You will notice that the only business object properties that are set to non default values are the DeleteConcurrencyType property and the UpdateConcurrencyType property which are both set to OptimisticRowVersion because I want users to be warned by a StrateFrame Data Collision dialog when they attempt to delete or save a record that another user has changed and saved first.  And of course the RowVersionOrTimestampColumn property is set to cust_Version which is the name of the rowversion column in the Customers table.  Also notice that the solution uses the default StrataFrame method of deleting records from the backend database table one at a time as soon as the user clicks the Delete button on the maintenance form toolstrip not when the user clicks the Save button.

Too see the problem, just open two separate copies of the Customer maintenance form displaying the same record from the backend Database table.  In the first form, edit the customer's name and save the record.  Then in the second form, delete the same record that the first form just edited and saved.  At this point, the second form should display a Data Collision dialog because the save that occurred on the first form caused the cust_Version field to be incremented which then caused the second form's delete to fail.  However, no Data Collision dialog appears.  The local internal data table record is deleted but the backend database table record is not deleted.  This can be proven by launching another copy of the Customer maintenance form and you will see the very record that the second form tried to delete.

In version of the StrataFrame file named businesslayer.vb at line 2442 you will see the call from the business layer to the data layer requesting deletion of the record.  After returning from that call to the data layer, the count (lnReturn) of how many records were affected is 0 which is correct because the record should not be and was not deleted because of the concurrency conflict which unfortunately was never displayed.  Even though the correct value for lnReturn is returned, the StrataFrame code never tests that value to determine if the deletion of the database table record succeeded.

Please let me know if you have successfully demonstrated the bug because I would sure like to get this problem fixed before the next release of the framework.

Sam Tenney
By Ivan George Borges - 12/15/2010 10:05:22 AM
Hi Sam.

Nope, it is not difficult at all to convince us of a bug, as long as we can reproduce it.

And yes, I had tested this for Greg already last week and thought he had comunicated with you about it. I was able to reproduce it and have forwarded this to the development team. Although it is a difficult situation, it can happen, so it will be checked and corrected, I am sure about it.

Thanks for the heads up. Wink
By Sam Tenney - 12/16/2010 4:09:20 AM
Hi Ivan,

Thanks for taking the time to reproduce the problem and to confirm that it is a bug.  I look forward to reviewing the solution to the problem so I can learn from the pros.

Sam Tenney
By Greg McGuffey - 12/16/2010 8:11:13 AM
Sorry I didn't post sooner on this Sam.  Ivan did a great job clarifying this and getting in front of the development team.  I dropped the ball letting you know. Sad

Site Map - Home - My Account - Forum - About Us - Contact Us - Try It - Buy It

Microsoft, Visual Studio, and the Visual Studio logo are trademarks or registered trademarks of Microsoft Corporation in the United States and/or other countries.