AnyDAC offers the TADEventAlerter component to listen for database alerts, send the alerts and manage them.
The DBMS alert refers to a database notification or alert sent by a database trigger or stored procedure with intent to notify a database client about some events at database side.
An alert is identified by the name and may include additional arguments. The clients are registering with the alerts. Multiple clients may register with a single alert, and single client may register with the multiple alerts. When an alert is signaled in a database, then all registered clients will be notified about that. When application is not more interested in an alert, it unregisters with the alert.
The classic examples of the alerts are:
Each DBMS implements DBMS alerts on their own. There is no standard for alerts mechanisms.
AnyDAC offers unified alerts API as the TADEventAlerter component. Some DBMS may implement few DBMS alert mechanisms. Each TADEventAlerter object may listen for few alerts by specifying their names in TADEventAlerter.Names property, and using single mechanism specified by TADEventAlerterOptions.Kind property.
AnyDAC listens for alerts in a background thread using an additional private connection to the database. The additional connection is created automatically by AnyDAC for each TADEventAlerter component. When the application creates multiple TADEventAlerter objects, consider to use pooled connections to improve performance.
To start receive the event alerts, fill in TADEventAlerter.Names property with required event names. Set Options.Kind to the event alerter kind or leave it empty to use the default alerter. Specify OnAlert event handler, which will be fired when an event is occurred. And set Active to True or call Register method. To stop receive the event alerts, set Active to False or call Unregister.
The OnAlert event handler may be called in the main or background thread contexts. Use Options.Synchronize property to control that. Note, application should minimize the run time of the background thread handler.
Application may set timeout for alerts by specifying Options.Timeout property. When there are no alerts for specified time, then the OnTimeout event handler will be called.
For example, to register for "Customers" alert using "DBMS_ALERT" mechanism on Oracle database and standard Firebird mechanism, use the code:
ADEventAlerter1.Names.Clear;
ADEventAlerter1.Names.Add('Customers');
case ADConnection1.RDBMSKind of
mkOracle: ADEventAlerter1.Options.Kind := 'DBMS_ALERT';
mkInterbase: ADEventAlerter1.Options.Kind := 'Events';
end;
ADEventAlerter1.Options.Synchronize := True;
ADEventAlerter1.Options.Timeout := 10000;
ADEventAlerter1.OnAlter := DoAlert;
ADEventAlerter1.OnTimeout := DoTimeout;
ADEventAlerter1.Active := True;
........
procedure TForm1.DoAlert(ASender: TADCustomEventAlerter;
const AEventName: String; const AArgument: Variant);
begin
if CompareText(AEventName, 'Customers') = 0 then
qryCustomers.Refresh;
end;
procedure TForm1.DoTimeout(ASender: TObject);
begin
// do something
end;
And the server side code for Oracle:
CREATE OR REPLACE TRIGGER TR_CUSTOMERS AFTER INSERT OR UPDATE OR DELETE ON CUSTOMERS BEGIN SYS.DBMS_ALERT.SIGNAL('Customers', '123'); END;
And for Firebird:
CREATE TRIGGER TR_CUSTOMERS FOR CUSTOMERS ACTIVE AFTER INSERT OR UPDATE OR DELETE BEGIN POST_EVENT 'Customers'; END;
As noted, every DBMS implements database alerts on her own. The alter mechanism kind is identified by TADEventAlerterOptions.Kind property value. If it is empty, then default mechanism will be used. For most mechanisms the client side functionality will be the same. The database side will differ.
The following table lists the DBMS and their alter mechanisms, supported by AnyDAC drivers:
|
DBMS |
Event alerter kind |
Description |
|
Advantage Database |
Events (*) |
Is used the standard Events (Notifications) functionality. To initiate an event, use sp_SignalEvent stored procedure. For example: sp_SignalEvent('Customers', true, 0, '123'); Note, that sp_SignalEvent may be called only from a stored procedure or a trigger. It cannot be called directly from the SQL command. |
|
Sybase SQL Anywhere |
Message (*) |
Is used the MESSAGE statement functionality. To initiate an event, the specially formatted message must be sent: _AD_$$<event name>[$$<argument>]. For example: MESSAGE '_AD_$$Customers$$123' |
|
Firebird / Interbase |
Events (*) |
Is used the standard FB/IB mechanism for event notifications. To initiate an event, use POST_EVENT <name> statement. For example: EXECUTE BLOCK AS BEGIN POST_EVENT 'Customers'; END; |
|
Microsoft SQL Server |
Query Notification (*) |
Is used the Query Update Notification service. The TADEventAlerter.Names content should have one of the following formats:
ALTER DATABASE <your db name> SET ENABLE_BROKER |
|
Oracle |
DBMS_ALERT (*) |
Is used the DBMS_ALERT package. Before the usage a DBA must execute GRANT EXECUTE ON DBMS_ALERT TO <user or group>. To initiate an event, use DBMS_ALERT.SIGNAL call. For example: BEGIN SYS.DBMS_ALERT.SIGNAL('Customers', '123'); END; |
|
|
DBMS_PIPE |
Is used the DBMS_PIPE package. Before the usage a DBA must execute GRANT EXECUTE ON DBMS_PIPE TO <user or group>. To initiate an event, use DBMS_PIPE.SEND_MESSAGE call. For example: BEGIN SYS.DBMS_PIPE.PACK_MESSAGE(123); SYS.DBMS_PIPE.SEND_MESSAGE('Customers'); END; |
|
PostgreSQL |
Notifies (*) |
Is used the standard event notification mechanism. To initiate an event, use NOTIFY <name> statement. PostgreSQL 9.0 supports payload argument, use NOTIFY <name> [, <paylod>]. For example: NOTIFY Customers |
|
SQLite |
Events (*) |
Is used the custom function POST_EVENT. To initiate an event, use POST_EVENT(<name>, [arg1 [,arg2 [,arg3 [,arg4]]]]). For example: SELECT POST_EVENT('Customers', 123) |
Note, the asterisk marks the default event alerter kind.
See AnyDAC demo AnyDAC\Samples\Comp Layer\TADEventAlerter\Main.
|
What do you think about this topic? Send feedback!
|