AnyDAC
ContentsIndexHome
PreviousUpNext
Database Alerts

AnyDAC offers the TADEventAlerter component to listen for database alerts, send the alerts and manage them.

Group
Links
General

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:

  • a table data change. In this case an application may refresh a dataset returning this table data.
  • a notification that some condition in data is met.
  • a notification to other application that one application will perform some special task, like data archiving or backup.

Each DBMS implements DBMS alerts on their own. There is no standard for alerts mechanisms. 

 

Using TADEventAlerter

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;

 

DBMS alert mechanisms

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:
  • CHANGE<index>=<message>;<SELECT query>. The event will be fired when the data returned by the SELECT query will be updated and the <message> will be returned as the event name. To fire an event an UPDATE statement against the selected data must be executed.
  • <message>. AnyDAC will create _AD_EVENTS table. The event will be fired when VALUE of the NAME=<message> row will be updated. To fire an event an UPDATE statement must be performed.
Additionally parameters may be specified in the Names:
  • SERVICE=<name>. The name of the service to use. '?' - means to create an uniquely named service and drop it after usage.
  • QUEUE=<name>. The name of the message queue to use. '?' - means to create an uniquely named queue and drop it after usage.
Note, to enable query notification execute the command:
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!