views:

1393

answers:

5

The trigger below is delaying my insert response. How can I prevent this?

create or replace
TRIGGER GETHTTPONINSERT
BEFORE INSERT ON TABLENAME
FOR EACH ROW 
Declare
  --   
BEGIN
  -- The inserted data is transfered via HTTP to a remote location
END;

EDIT People are telling me to do batch jobs, but I would rather have the data earlier than having 100% consistency. The advantage of the trigger is that it happens as soon as the data arrives, but I can't afford the insert response delay.

A: 

well obviously, you could prevent the delay by removing the Trigger.... Else, the trigger will ALWAYS be executed before your insert, thats what the TRIGGER BEFORE INSERT is made for.

Or maybe you could give us more details on what you need exactly?

guigui42
and if the trigger was changed to AFTER insert? would it solve my problem?I need to transfer all data that is inserted in my table to a remote location which has an HTTP interface
Jader Dias
Well, since the HTTP thing would be triggered AFTER the insert, the insert wont be delayed anymore by the HTTP request.So it could be worth a try.
guigui42
strangely it didn't work
Jader Dias
The AFTER trigger would not be any better. So the row is inserted, but not commited, what's the advantage of that?
ammoQ
@ammoQ Thanks for explaining why it does not work
Jader Dias
@Jader Dias, What didn't work? It didn't send data via HTTP, there was some kind of error or the performance didn't improve?
tuinstoel
The insert time didn't lower to the same response time it had before the creation of the trigger.
Jader Dias
In other words, the insert is waiting for the HTTP request to complete.
Jader Dias
+10  A: 

One approach is to have the trigger create a dbms_job that runs once (each) time to perform the http transfer. The dbms_job creation is relatively quick and you can think of this as effectively spawning a new thread in parallel.

See http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:7267435205059 for further info - his example deals with sending email, but the idea is the same.

dpbradley
The Trigger has an advantage of executing earlier, which is important to me.
Jader Dias
if you have sufficient job_queue_processes available the job will be picked up with no significant delay - creating the job from the trigger does participate in the overall transaction however, so the creation of the job will be delayed until the commit (but this is mostly a good thing, since a rollback will not create the job/initiate the transfer)
dpbradley
it will do, I will try, thanks
Jader Dias
If you are on 10G or above you might have a look at the job scheduler before you use dbms_job, I haven't played with it too much yet but there may be more options and it is the replacement for dbms_job. You could also look at using queuing or dbms_pipe to set up a process to handle the request almost instantly.
Ethan Post
@Ethan - AQ and pipe are certainly other options. Be careful with dbms_scheduler though, I believe in 10g it commits internally as part of its processing and you wouldn't want it in the middle of your transaction.
dpbradley
Yes, dbms_scheduler does a commit when you SUBMIT the job, dbms_job doesn't. I really think you should not use dbms_scheduler in this case. See also http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:25405608521707#75146917178353
tuinstoel
@tuinstoel... nice point, thanks!
Mark Harrison
+3  A: 

Maybe you could create a local table that store the info do you have to transfer, and create a job that executes every X minutes. The job read from the table, transfer all the data and delete the transfered data from the table.

Jonathan
+1  A: 

Isn't it possible to use the Oracle replication options? You send your inserted data via http to a remote location in an after or before statement trigger. What will happen when there is a rollback? Your hhtp send message will not be rollbacked so you have inconsistent data.

tuinstoel
Inconsistent data is not a problem on my scenario
Jader Dias
Which kind of communication Oracle replication requires? Will it work over the internet or it requires a VPN?
Jader Dias
You can use Oracle Streams to sync two or more databases that are geoghraphically separated, the internet will be used.
tuinstoel
+2  A: 

There is a perfect solution for this exact situation called Database Change Notification.

You can think of it almost exactly like an async trigger.

You use the DBMS_Change_Notification package to tell oracle which tables to watch and what to do when a change occurs. You can monitor for DML and DDL, you can have Oracle batch the changes (i.e. wait for 10 changes to occur before firing). It will call a sproc with an object containing all the rowids of the changed rows... you can decide how to handle, including calling HTTP. It will not have to finish for the insert to commit. Documentation for 10gR2

Stephanie Page
Thanks! I saw it after your comment on my blog
Jader Dias