Multiple queries; pain in the ASSynchronous (1 Viewer)

NauticalGent

Ignore List Poster Boy
Local time
Today, 06:42
Joined
Apr 27, 2015
Messages
6,367
Seen a few posts on here and other forums regarding asynchronous queries. Thought to myself that I would never have that problem; my queries are simple and the number of records are small. Never say never.

I have heard good and bad regarding DoEvents, so I decided to try something different. I placed each query in a separate function and call them (4) one after the other.

It SEEMS to be working, but if I thought of it, someone a lot smarter than me has too...but I can't find anything that speaks to this.

Am I just getting lucky or am I correct in thinking the the query would execute completly before returning to the module that called it?
 

sneuberg

AWF VIP
Local time
Today, 03:42
Joined
Oct 17, 2014
Messages
3,506
Am I just getting lucky or am I correct in thinking the the query would execute completly before returning to the module that called it?

I believe that's normally the case. I'd like to see a way in an Access only database (no SQL Server backend) where you could make a query asynchronous. If you had a query that took a long time to run you could return control to the user so that he could do other things while the query ran. You would need to have some event fire when the query was complete.
 

NauticalGent

Ignore List Poster Boy
Local time
Today, 06:42
Joined
Apr 27, 2015
Messages
6,367
Not sure what exactly you saying Steve. What I experienced today was very strange. When I ran the queries separately, I got the correct results. When I ran them with code (Currrentdb.Execute "query", dbFailOnError) one to the queries seems to abort before it completly runs.

Darndest thing. Seems it is not as uncommon as I thought.
 

GohDiamond

"Access- Imagineer that!"
Local time
Today, 06:42
Joined
Nov 1, 2006
Messages
550
I have a large database that I administer and there have been instances where the largest of the queries causes an error "System Resources Exceeded". Could this be an indicator of something like multiple queries attempting asynchronous execution when one is set to fire right after the other?
I have commented out all instances of DoEvents in the dB and still occasionally get this error. We are using Office 2013, ergo Access 2013.

Did you get any error when you experienced your issue? or were the results just not as expected?

Just wondering,
Cheers
Goh
 

Galaxiom

Super Moderator
Staff member
Local time
Today, 20:42
Joined
Jan 20, 2009
Messages
12,853
When I ran the queries separately, I got the correct results. When I ran them with code (Currrentdb.Execute "query", dbFailOnError) one to the queries seems to abort before it completly runs.

When queries are run directly, they are processed by Access then sent to the ACE/JET engine. CurrentDb.Execute is a method of the database so VBA is bypassing Access and sending the command directly to engine.

It may be that no further processing is done when Access is control but VBA can keep sending without waiting for the engine to complete the task.

It would be informative to know what happens when using DoCmd.RunSQL from VBA to run the query instead. This is a method if the Application, so Access is in the loop.
 

sneuberg

AWF VIP
Local time
Today, 03:42
Joined
Oct 17, 2014
Messages
3,506
When queries are run directly, they are processed by Access then sent to the ACE/JET engine. CurrentDb.Execute is a method of the database so VBA is bypassing Access and sending the command directly to engine..

Are you saying the ACE/JET engine has it's own thread or process? I always thought all the code was executed by a single process in a singe thread in the frontend.
 

gemma-the-husky

Super Moderator
Staff member
Local time
Today, 11:42
Joined
Sep 12, 2006
Messages
15,660
I believe that's normally the case. I'd like to see a way in an Access only database (no SQL Server backend) where you could make a query asynchronous. If you had a query that took a long time to run you could return control to the user so that he could do other things while the query ran. You would need to have some event fire when the query was complete.

as far as I am aware, an action query is "atomic"

set it running, and watch the progress bar.
 

NauticalGent

Ignore List Poster Boy
Local time
Today, 06:42
Joined
Apr 27, 2015
Messages
6,367
:rolleyes:
I Did you get any error when you experienced your issue? or were the results just not as expected?
Goh

No errors, just inconsistent results. To be more specific, the Update query is run on a table that holds parsed text. What the query is doing is assigning then PK value before adding it to the master table.

The next query is another type of action query against the same temp table. If I run the two queries back-to-back, not all of the PK values get Updated. If I run them separately, no issues occur.

As I said in the original post, on a whim, I placed both queries inside their own Public Sub and it works...but I am wondering if I just got lucky or if I am on to something...
 

NauticalGent

Ignore List Poster Boy
Local time
Today, 06:42
Joined
Apr 27, 2015
Messages
6,367
When queries are run directly, they are processed by Access then sent to the ACE/JET engine. CurrentDb.Execute is a method of the database so VBA is bypassing Access and sending the command directly to engine.

... It would be informative to know what happens when using DoCmd.RunSQL from VBA to run the query instead. This is a method if the Application, so Access is in the loop.

Interesting, I was unaware and that makes sense. I went with the Currentdb.Execute method because I had learned (on the forum) that they are more efficient and eliminates the need for SetWarnings.

I will give it a go and get back to you.
 

sneuberg

AWF VIP
Local time
Today, 03:42
Joined
Oct 17, 2014
Messages
3,506
If I run the two queries back-to-back, not all of the PK values get Updated. If I run them separately, no issues occur.

I'd really like to get a better understanding of this issue. Please explain how queries are run back-to-back vs separately. Do you mean two Currentdb.Execute methods in the same procedure for back-to-back vs running them in different procedures?
 

The_Doc_Man

Immoderate Moderator
Staff member
Local time
Today, 05:42
Joined
Feb 28, 2001
Messages
27,223
When we are talking about Access databases, split or not, if Access is running the FE and the BE then NOTHING in Access itself including the VBA code is asynchronous - with the possibility of physical faults (i.e. power fail, device interrupt, device error, and memory management faults) leading to traps that can interrupt event code. (That's why you use Exit Sub for something that gets called, including Event code, but you use Resume Next or Resume label-name after a trap. Two different call contexts.)

That is because Access, which is explicitly written single-threaded, can never make use of the multiple processors in a machine that has them. That fact was discussed in some MSDN articles, though it has been a while since I read that. Oh, the thread running Access might bounce from one CPU to another as part of the normal process scheduler functions, but NO PART of Access itself is capable of asynchronous operation except for the aforementioned hardware traps. It just isn't written that way. Even the VBA code is not really "running." It is being interpreted synchronously because VBA is a PSEUDO-compiler. Note that a DLL written in a truly compiled language, even VB6, CAN go asynch - but that is not anything that MSACCESS.EXE handles.

The event code is synchronous because Access TESTS for each event in the main program and dispatches (calls via table) the appropriate event code. As the event occurs, Access tests whether the object in question has an Event Code pointer as part of its object properties sheet. The actual event occurs whether or not a routine has been declared. That is, the form opens even if no Form_Open event routine exists. Remember also that event codes CANNOT interrupt other event codes (again, with the hardware trap exception).

Where asynchronicity occurs is in the SQL engine that comes with Access. JET for older versions and ACE for the newer versions were indeed written with the ability to go multi-threaded. So once you leave the domain of Access and let SQL get executed by an SQL execution engine, there is where the issue becomes trickier to discuss.

According to the MSDN articles, JET and ACE have the ability to use multiple threads, though what I had read made it seem like only the cleanup might go asynch on you.

Gent, if you want to experiment on this, set up your test to run those two queries in-line but separate them with a DBEngine.Idle (and you'll have to look up the correct argument for this case, I'm posting from home and I don't keep Access open here like I used to at the office). See if the problem you described occurs when you force Access to wait for the underlying engine to go idle between successive queries.

Supplement: Use DBEngine.Idle dbRefreshCache

Also, if you use the DAO-based DAODB.Execute "query" command, you should ALWAYS include dbFailOnError as the second parameter, and you should be prepared to trap errors when the .Execute fails. The good news about the .Execute is that it is supposed to "roll back" when an error triggers that "fail" trap. I used that a lot with the SPAWAR NEDC NO database that was my main Access project. Worked like a champ.

From your first post:

Am I just getting lucky or am I correct in thinking the the query would execute completly before returning to the module that called it?

Not necessarily lucky or unlucky. The query will return results to its caller - but the moment it does, that caller (your separate subroutine) returns to the fully synchronous environment that is controlled by Access. To the best of my understanding when I read up on this, the window during which that asynchronicity exists is very short anyway. By forcing the code back into that single-thread environment, you give it time to "catch up" with the main thread.
 
Last edited:

NauticalGent

Ignore List Poster Boy
Local time
Today, 06:42
Joined
Apr 27, 2015
Messages
6,367
I'd really like to get a better understanding of this issue. Please explain how queries are run back-to-back vs separately. Do you mean two Currentdb.Execute methods in the same procedure for back-to-back vs running them in different procedures?

Sure thing Steve,

Back to back, the code looks like this:

...
Currentdb.Execute "qryNum1", dbFailOnError
Currentdb.Execute "qryNum2", dbFailOnError

When I say separately, it is by using the Access application; double-clicking the query in the navigation pane one at a time.

Also, separately means putting each query in it's own Public Sub and calling them individually from the main Sub. When I did this, the results were as if I had run them from the Navigation Pane. I was pondering if the individual Subs ensured complete execution before returning to the main Sub or did the process of calling and returning just simply "slow it down" enough to give me the appearance of "complete execution".

Also, to more clear, the main Sub is called from a cmdButton on a form.

Clear as mud?
 
Last edited:

Minty

AWF VIP
Local time
Today, 11:42
Joined
Jul 26, 2013
Messages
10,371
This is interesting, completely un-related to queries but possibly demonstrating similar issues; I create and run a batch file locally to update the FE that is called from the FE. When the updater is called from access even though access is closed by the call to the batch, if the process takes longer than the FE takes to copy over the network, the batch file tries to reopen the new FE before it has finished copying, and bombs out.
This never happens if your manually run the batch file.
 

NauticalGent

Ignore List Poster Boy
Local time
Today, 06:42
Joined
Apr 27, 2015
Messages
6,367
I had a similar problem because I use a VBS to install/update my FE as well. To fix this, I added the line:

WSCRIPT.Sleep 5000

On a possibly related note, ALL of my Shell commands no longer work. I assume our IT pushed some updates that are causing the problem but they have not confirmed this OR fixed it.

F-R-U-S-T-R-A-T-I-N-G...
 

NauticalGent

Ignore List Poster Boy
Local time
Today, 06:42
Joined
Apr 27, 2015
Messages
6,367
Gent, if you want to experiment on this, set up your test to run those two queries in-line but separate them with a DBEngine.Idle (and you'll have to look up the correct argument for this case, I'm posting from home and I don't keep Access open here like I used to at the office). See if the problem you described occurs when you force Access to wait for the underlying engine to go idle between successive queries.

Supplement: Use DBEngine.Idle dbRefreshCache

Doc/Galaxiom, as usual, your advice was spot-on and surprisingly not so esoteric (On Doc's part that is; you are either learning how to dumb-down your prose or I may be getting smarter(!))

I was expecting a HUGE lag because I used it on every action query (6 and counting). I loaded the test with 300 messages (as opposed to the 20+ I used yesterday) to parse and it performed with no noticeable delay - but what is more, all the actions were completed.

Grazie mille, a mille times over, hope you're enjoying your retirement!
 

sneuberg

AWF VIP
Local time
Today, 03:42
Joined
Oct 17, 2014
Messages
3,506
Sure thing Steve,

Back to back, the code looks like this:

...
Currentdb.Execute "qryNum1", dbFailOnError
Currentdb.Execute "qryNum2", dbFailOnError

When I say separately, it is by using the Access application; double-clicking the query in the navigation pane one at a time.

Also, separately means putting each query in it's own Public Sub and calling them individually from the main Sub. When I did this, the results were as if I had run them from the Navigation Pane. I was pondering if the individual Subs ensured complete execution before returning to the main Sub or did the process of calling and returning just simply "slow it down" enough to give me the appearance of "complete execution".

Also, to more clear, the main Sub is called from a cmdButton on a form.

Clear as mud?

Thanks. This is clear enough. The thrust of this thread is that actions in qryNum2 can occur before the completion of the actions is qryNum1. I intend on playing with this when I get time. Since your queries are known to cause problems I would like to see them so I could set up similar test cases. Could you post the SQL of your queries?
 

sneuberg

AWF VIP
Local time
Today, 03:42
Joined
Oct 17, 2014
Messages
3,506
Where asynchronicity occurs is in the SQL engine that comes with Access. JET for older versions and ACE for the newer versions were indeed written with the ability to go multi-threaded. So once you leave the domain of Access and let SQL get executed by an SQL execution engine, there is where the issue becomes trickier to discuss.

Thanks for you post. First please understand that not trying to be argumentative but I am only trying to get a better understanding of this issue. If collisions can occur between queries then that's something all Access developers need to be aware of. But here the question. If Access is single threaded then in what process would these threads of the SQL engine run? Does Access spawn a new process when CurrentDB.Execute is executed?
 

Users who are viewing this thread

Top Bottom