Reputation: 1320
I'm developing a client/server application using Android as a client and JBoss AS 7.x as the server. I am doing all of this via a servlet and the DataSource is configured to make use of connection pooling.
One of the requirements is to immediately invalidate the client session when certain data from the DataSource(Oracle) is deleted. For this I was checking the DBMS_ALERT.
As far as I can understand DBMS_ALERT needs a polling mechanism that will "hang" the application until a notification occurs. So my servlet will halt all operations and wait for the notification. Please correct me if I'm wrong as I have little to no experience with PL/SQL.
I have already checked the resources provided in this question but I didn't manage to understand what's the right track to take.
The code for the DBMS_ALERT DataSource side is:
CREATE OR REPLACE TRIGGER apps0000_datuser_biur
BEFORE INSERT OR UPDATE OR DELETE on apps0000_t
REFERENCING NEW AS NEW OLD AS OLD
for EACH ROW
begin
if (deleting) then
DBMS_ALERT.signal('appdelete',:old.APPS_PACKAGE);
end if;
end;
The code for the DBMS_ALERT servlet side is(please correct me if I got something wrong here):
try {
String strDSName1 = "java:/OracleDSJNDI";
ctx = new InitialContext();
ds1 = (javax.sql.DataSource) ctx.lookup(strDSName1);
} catch (Exception e) {
System.out.println("ERROR getting 1'st DS : " + e);
}
conn = ds1.getConnection();
String sql = null;
String message = null;
String status = null;
sql = "{call dbms_alert.register('appdelete')}";
CallableStatement cs1 = conn.prepareCall(sql);
cs1.execute();
sql = "{call dbms_alert.waitone('appdelete', ?, ?, ?)}";
CallableStatement cs2 = conn.prepareCall(sql);
cs2.registerOutParameter(1, Types.VARCHAR);
cs2.registerOutParameter(2, Types.VARCHAR);
cs2.registerOutParameter(3, Types.VARCHAR);
int x = 0;
while (x == 0) {
cs2.execute();
String Result = cs2.getString(1);
System.out.print(Result + "\n");
}
My question is: How do I implement this in my servlet without causing it to hang when it reaches the DBMS_ALERT part(if it's a viable solution)?
Thanks
Upvotes: 1
Views: 1018
Reputation: 12169
If you look at the message function in the API documentation, it shows:
DBMS_ALERT.WAITONE (
name IN VARCHAR2,
message OUT VARCHAR2,
status OUT INTEGER,
timeout IN NUMBER DEFAULT MAXWAIT);
The "timeout" parameters defaults to forever. The comments state:
timeout
Maximum time to wait for an alert.
If the named alert does not occurs before timeout seconds, this returns a status of 1.
So, you could set this timeout to some # of seconds, and then poll in a loop. HOWEVER, I would contend that it is a poor approach, as you are just eating network and application/server resources using polling. If possible, I would take a look at using Oracle Advanced Queuing which allows for total async processing (See DBMS_AQ package).
Upvotes: 2