views:

40

answers:

1

I had a user email me with an error message that occurred when he was attempting to save a record to an Access 2003 database. Nothing unusual other than the error message that she can't save database design changes and she was only attempting to save a record.

Here is the full error message ...

"Microsoft Office Access can't save design changes or save to a new database object because another user has the file open. To save your design changes or to save to a new object, you must have exclusive access to the file."

In the users system Access 2003 is used as a font end where all data is stored in SQL Server 2008. There are a few users in the system so it is entirely possible that two users where accessing the same record. It is the fact that the error message seemed to indicate a design change was what was being attempted when all the user was trying to do was save the record data.

Any thoughts?

+2  A: 

This is not an answer to your question (I think HansUp has provided the most plausible explanation of the problem), but an explanation of why you should never share a front end.

Before Access 2000, the definitions of user interface objects of a front end (forms, reports, modules, etc.) were stored in a system table with one record per object. When A2000 was introduced, MS changed this in order that the VBE could be incorporated into Access (for consistency with other Office apps that hosted VBA). This necessitated changing the way code-bearing objects (or potentially code-bearing) were stored. Instead of one record per object in a system table, all Access objects in the VBA project are stored in a monolithic BLOB field in a single record in a system table.

Now, back up for a minute, and consider how the old version worked.

When a user edits a form and saves the edits, only the record in the system table that represents that form is altered. Likely there would be no possible concurrency issues if multiple users were using that front end because they wouldn't all have the same system table records loaded nor be updating them simultaneously.

You might say "but I'm not making design changes in my front end!"

But you'd be wrong. Access transparently saves certain user-altered properties of the form, particularly filters and sorts. Unless you close a form with DoCmd.Close acForm, Me.Name, acSaveNo, user changes to filters and sorts will be saved to the definition of the form behind the scenes. There are potentially other properties that can get saved explicitly when a user presses the Ctrl-S key command, such as form size and location. Other changes might cause a prompt, such as if a user hides/resizes columns in a datasheet form (dunno exactly what happens there -- probably requires Ctrl-S).

Now, consider what was happening in A97 and before -- each form that is represented by a record in a system table might get updated each time a user closes it, but there's not much in the way of collisions, none of the users have the form open in design mode, so everybody is using optimistic locking, so when they close the form, their changes get saved. Now, if another user closes the form, it may be they get a prompt that another user has changed the form, but maybe not (I wouldn't know as I never once shared a front end in any version of Access ever).

With A2000, every change to every user interface object in a front end is a change to the data stored in a single monolithic BLOB field in a single record. That means there are guaranteed concurrency issues with multiple users trying to update the same field in a single record.

Secondly, it's a massive BLOB field, the internal structure of which is quite complicated, but completely unknown to Jet/ACE (which is actually handling the reading and saving of data in that field).

To put this in regular database application terms, sharing a front end is like having a database application with a memo field where all the users are trying to type into the same memo field in a single record simultaneously. This would lead to terrible concurrency problems, and likely corrupt the memo pointers fairly quickly.

When you share an Access front end, you're doing EXACTLY THE SAME THING -- making all your users edit a single field in a single record simultaneously.

Once you understand this, it should be self-evident that you should never do this.

David-W-Fenton
Awesome explanation David! Thank you very much.
webworm