Database Alerts (FireDAC)
Go Up to Working with Commands (FireDAC)
The DBMS alert refers to a database notification or alert sent by a database trigger or stored procedure with the purpose of notifying a database client about some events at database side.
An alert is identified by name and can include additional arguments. The clients are registering with alerts. Multiple clients can register with a single alert, and one client can register with multiple alerts. When an alert is signaled in a database, all registered clients will be notified about that. When an alert is not used anymore, the application unregisters from that alert.
Classic examples of alerts are:
- A table data change. In this case, an application refreshes a dataset returning this table data.
- A notification about some condition in data being met.
- A notification sent to other applications, that a specific application will perform some special task, such as data archiving or backup.
Each DBMS implements DBMS alerts on their own. There is no standard for alerts mechanisms.
Using TFDEventAlerter
FireDAC offers unified alerts API as the TFDEventAlerter component. Some DBMS may implement few DBMS alert mechanisms. Each TFDEventAlerter object listens for several alerts by specifying their names in the TFDEventAlerter.Names property, and using a single mechanism specified by the Options.Kind property.
FireDAC listens for alerts in a background thread using an additional private connection to the database. This additional connection is created automatically by FireDAC for each TFDEventAlerter component. When the application creates multiple TFDEventAlerter objects, consider using pooled connections to improve the performance.
To start receiving the event alerts, fill in the TFDEventAlerter.Names property with the required event names. Set Options.Kind to the event alerter type or leave it empty to use the default alerter. Specify the OnAlert event handler that will be fired when an event occurs, and set Active to True or call the Register method. To stop receiving the event alerts, set Active to False or call Unregister.
The OnAlert event handler can be called in the main or background thread contexts. Use the Options.Synchronize property to control that.
- Note: The application should minimize the runtime of the background thread handler.
The application sets timeout for alerts by specifying the Options.Timeout property. When there are no alerts for a specified period of time, the OnTimeout event handler is called.
For example, to register for the "Customers" alert using the "DBMS_ALERT" mechanism on Oracle database and the standard Firebird mechanism, use the following code:
FDEventAlerter1.Names.Clear;
FDEventAlerter1.Names.Add('Customers');
case FDConnection1.RDBMSKind of
mkOracle: FDEventAlerter1.Options.Kind := 'DBMS_ALERT';
mkInterbase: FDEventAlerter1.Options.Kind := 'Events';
end;
FDEventAlerter1.Options.Synchronize := True;
FDEventAlerter1.Options.Timeout := 10000;
FDEventAlerter1.OnAlter := DoAlert;
FDEventAlerter1.OnTimeout := DoTimeout;
FDEventAlerter1.Active := True;
// …
procedure TForm1.DoAlert(ASender: TFDCustomEventAlerter;
const AEventName: String; const AArgument: Variant);
begin
if CompareText(AEventName, 'Customers') = 0 then
qryCustomers.Refresh;
end;
procedure TForm1.DoTimeout(ASender: TObject);
begin
// …
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;
For Firebird, use the following code:
CREATE TRIGGER TR_CUSTOMERS FOR CUSTOMERS
ACTIVE AFTER INSERT OR UPDATE OR DELETE
BEGIN
POST_EVENT 'Customers';
END;
DBMS Alert Mechanisms
As noted before, every DBMS implements database alerts on its own. The alter mechanism type is identified by the TFDEventAlerterOptions.Kind property value. If this is empty, the default mechanism is used. For most mechanisms, the client-side functionality is the same, only the database-side functionality is different.
The following table lists the DBMS and their alter mechanisms, supported by the FireDAC 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');
|
Sybase SQL Anywhere | Message (*) | The MESSAGE statement functionality is used. To initiate an event, a specially formatted message of this kind: _FD_$$<event name>[$$<argument>] must be sent. For example:
MESSAGE '_FD_$$Customers$$123' |
DataSnap server | Callbacks (*) | DataSnap “heavyweight” callbacks are used (for more information, see Delphi Labs: DataSnap XE - Callbacks). The TFDEventAlerter.Names content should have one of the following formats:
|
DB2 | DBMS_ALERT (*) | The DBMS_ALERT package is used. Before the usage, a DBA must execute GRANT EXECUTE ON DBMS_ALERT TO <user or group>. To initiate an event, use the DBMS_ALERT.SIGNAL call. For example:
CALL DBMS_ALERT.SIGNAL('Customers', '123'); |
DBMS_PIPE | The DBMS_PIPE package is used. Before the usage, a DBA must execute GRANT EXECUTE ON DBMS_PIPE TO <user or group>. To initiate an event, use the DBMS_PIPE.SEND_MESSAGE call. For example:
BEGIN CALL DBMS_PIPE.PACK_MESSAGE(123); CALL DBMS_PIPE.SEND_MESSAGE('Customers'); END; | |
Firebird | Events (*) | The standard Firebird mechanism for event notifications is used. To initiate an event, use the POST_EVENT <name> statement. For example:
EXECUTE BLOCK AS BEGIN POST_EVENT 'Customers'; END; |
Informix | DBMS_ALERT (*) | The DBMS_ALERT package is used from External Compatibility Package. To initiate an event, use the DBMS_ALERT_SIGNAL call. For example:
EXECUTE PROCEDURE DBMS_ALERT_SIGNAL('Customers', '123') |
Interbase | Events (*) | The standard InterBase mechanism for event notifications is used. To initiate an event, use the POST_EVENT <name> statement from a trigger or a stored procedure. Client-side initiating is not supported. |
Microsoft SQL Server | QueryNotifies (*) | The Query Update Notification service is used. The TFDEventAlerter.Names content should have one of the following formats:
Additionally, these parameters can be specified in the Names:
ALTER DATABASE <your db name> SET ENABLE_BROKER |
MongoDB | Tail (*) |
Uses a tailable cursor on a given capped collection to alert about insertions. The Names property of the alerter must contain a single value using one of the following formats to indicate the target capped collection:
Where:
When an insertion occurs, your handler for the OnAlert event receives the inserted document as a JSON string ( |
Oracle | DBMS_ALERT (*) | The DBMS_ALERT package is used. Before the usage, a DBA must execute GRANT EXECUTE ON DBMS_ALERT TO <user or group>. To initiate an event, use the DBMS_ALERT.SIGNAL call. For example:
BEGIN SYS.DBMS_ALERT.SIGNAL('Customers', '123'); END; |
DBMS_PIPE | The DBMS_PIPE package is used. Before the usage, a DBA must execute GRANT EXECUTE ON DBMS_PIPE TO <user or group>. To initiate an event, use the DBMS_PIPE.SEND_MESSAGE call. For example:
BEGIN SYS.DBMS_PIPE.PACK_MESSAGE(123); SYS.DBMS_PIPE.SEND_MESSAGE('Customers'); END; | |
QueryNotifies | The Continuous Query Notification (CQN) feature is the Oracle implementation of The Data Change Notification feature. For more information, see Oracle CQN and Continuous Query Notification. | |
PostgreSQL | Notifies (*) | The standard event notification mechanism is used. To initiate an event, use the NOTIFY <name> statement. PostgreSQL 9.0 supports payload arguments, use NOTIFY <name> [, <paylod>]. For example:
NOTIFY Customers |
SQLite | Events (*) | The POST_EVENT custom function is used. 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 Also
- Multithreading
- TFDEventAlerter sample application