One common concern about using asynchronous execution mode is
the assumption that you can’t start executing a
SQLStatement
instance
if another SQLStatement is currently executing against the same
database connection. In fact, this assumption isn’t correct. While
a SQLStatement instance is executing you can’t change the
text
property
of the statement. However, if you use a separate SQLStatement instance
for each different SQL statement that you want to execute, you can
call the
execute()
method of a SQLStatement while another
SQLStatement instance is still executing, without causing an error.
Internally, when you’re executing database operations using asynchronous execution
mode, each database connection (each
SQLConnection
instance)
has its own queue or list of operations that it is instructed to
perform. The runtime executes each operation in sequence, in the
order they are added to the queue. When you create a SQLStatement
instance and call its
execute()
method, that statement
execution operation is added to the queue for the connection. If
no operation is currently executing on that SQLConnection instance,
the statement begins executing in the background. Suppose that within
the same block of code you create another SQLStatement instance
and also call that method’s
execute()
method. That
second statement execution operation is added to the queue behind
the first statement. As soon as the first statement finishes executing,
the runtime moves to the next operation in the queue. The processing of
subsequent operations in the queue happens in the background, even
while the
result
event for the first operation
is being dispatched in the main application code. The following
code demonstrates this technique:
// Using asynchronous execution mode
var stmt1 = new air.SQLStatement();
stmt1.sqlConnection = conn;
// ... Set statement text and parameters, and register event listeners ...
stmt1.execute();
// At this point stmt1's execute() operation is added to conn's execution queue.
var stmt2 = new air.SQLStatement();
stmt2.sqlConnection = conn;
// ... Set statement text and parameters, and register event listeners ...
stmt2.execute();
// At this point stmt2's execute() operation is added to conn's execution queue.
// When stmt1 finishes executing, stmt2 will immediately begin executing
// in the background.
There is an important side effect of the database automatically
executing subsequent queued statements. If a statement depends on
the outcome of another operation, you can’t add the statement to
the queue (in other words, you can’t call its
execute()
method)
until the first operation completes. This is because once you’ve
called the second statement’s
execute()
method,
you can’t change the statement’s
text
or
parameters
properties.
In that case you must wait for the event indicating that the first
operation completes before starting the next operation. For example,
if you want to execute a statement in the context of a transaction,
the statement execution depends on the operation of opening the
transaction. After calling the
SQLConnection.begin()
method to
open the transaction, you need to wait for the SQLConnection instance
to dispatch its
begin
event. Only then can you
call the SQLStatement instance’s
execute()
method.
In this example the simplest way to organize the application to
ensure that the operations are executed properly is to create a
method that’s registered as a listener for the
begin
event.
The code to call the
SQLStatement.execute()
method
is placed within that listener method.