Trigger on standard oracle base table recommended ? Oracle application - java

I want to write trigger on oracle application( ERP) one of the vital base table wf_notifications , from this trigger I will be calling a java concurrent program using fnd_request.submit_request , all of my operations I will be doing in this java class file used in concurrent program . so will other operations affect if concurrent program fails ??? on other side oracle dose'nt recommend writing triggers on oracle standard base tables

If you put a trigger on a table and the trigger throws an exception your DML statement (insert, update, delete) will fail with that exception.
You can put an catch all exception handler in the trigger to make sure your DML continues to work even if the trigger fails but you may never no that there is a problem with the triggered function.
So that would be something along these lines:
create or replace trigger mytrigger
before insert or update or delete
on mytable
for each row
declare
begin
fnd_request.submit_request;
exception
-- Hide whatever error this trigger throws at us.
when others then null;
end mytrigger;
Also, the trigger could slow down your table inserts and updates because of the extra work being done.

Related

Batch delete throws QueryCollectorSignal exception?

When I try to do a batch delete, nothing happens. I stepped into the debugger, and see that BatchCRUD::executeAction calls UpdatableRecord::delete, and down in the callstack, UpdatableRecordImpl::checkIfChanged calls fetchOne() which throws a QueryCollectorSignal. The sql executed works fine in PGAdmin (postgres), so I'm wondering what's going on here? How do I do a proper batch delete?
When does this happen:
you have turned on the executeWithOptimisticLocking setting
this particular table doesn't have any timestamp or version column
Why does this happen?
batchStore(), batchDelete() and similar calls execute the respective store(), delete() etc. calls on each individual UpdatableRecord, but with an ExecuteListener that aborts execution (via this QueryCollectorSignal exception) and just collects the SQL query that would have been executed. It then batches these SQL queries, rather than executing them individually. The ExecuteListener is, unfortunately, also applied to the SELECT query that is needed for optimistic locking.
The safest solution would probably be to just turn off optimistic locking before we provide a fix. I've registered an issue for this:
https://github.com/jOOQ/jOOQ/issues/5383

Purging Process halts after running 10 delete queries

I have a requirements to create a purging program using Java to purge record from database. Records will be purged from each tables before certain date (depending on defined in property file).
I have created program and decided all tables in to certain functions (NOT database function, but Java functions user defined) so that it can handles interdependent tables together. This program runs fine till 10 queries (first 4 functions) but halts at 5 the function of sequence defined.
In this case it does not throw any errors / exception. Looks to be keep executing it.
I have created Java functions like below.
purgeDatabaseOperations.purgeClsOfSvcHistTable(date);
purgeDatabaseOperations.purgeWmUiScrnChgLgTable(date);
each function may have more then 1 delete queries, each queries is getting added to array list and passed to database purging to be actually purging from database using stmt.executeBatch() function.
For now as i am doing testing, i am not explicitly committing database and defined connection.setAutoCommit(false) in my code so it will NOT commit to database.
Do anyone really know what could be the cause of program to get halts? Where do i need to start digging. I have tried reordering functions but did not help.
Regards,
Jay Shukla

Need a program that continously listens to the Oracle DB and if any DML's are made it calls another program?

I have an Oracle DB with a lot of tables ... How can I write something which listens to the Oracle DB and if any changes are made to the DB, it calls another program which does some processing
It would be asnync
I just need to trigger a java program if there is any kind of DML happening .. I dont want details about which table or what rows or new/old values ...
If there is a DML on any table in a DB call a java program thats it
http://docs.oracle.com/cd/B14117_01/win.101/b10118/o4o00118.htm
OracleDB has some events. Just try to use them; For example, when the db is updated - And to call another java program:
Runtime.getRuntime().exec(/Here the argument/);
I fear you're setting yourself up for failure here. I suggest a related, but slightly different course of action.
Rather than trigging your processing on every data change, consider instead having your processing run every X minutes/hours/whatever using something like Cron or Quartz.
If you're worried about having it run when no changes have been made, you can add triggers to your tables to update a "last updated" table and you can abort if no changes have been made since the last run.
This avoids the biggest concern you would have with an "on-update-processor", namely what do you do if there's an update, which triggers a process, and while that process is running another update happens. Do you trigger another process? What if they conflict? I think you'll find it better to allow there to be a slight delay between the update and the synchronization process.
That's a pretty tall order for a question.
For starters, you are going to need a way to detect that a DML operation (INSERT, UPDATE, DELETE) has occurred.
For auditing on individual tables, we can use TRIGGERS.
CREATE TRIGGER [BEFORE|AFTER] [INSERT][UPDATE][DELETE] ... [FOR EACH ROW]
The normative action is to record information about the information (whatever is needed later) in an "audit log" table. You have to make a decision whether the operations you need to perform are synchronous (should happen before the DML completes) or whether those operations can be asynchronous (can happen anytime after the DML completes).
Normally, synchronous processing is done in PL/SQL, but Oracle does provide a mechanism for calling external procedures (EXTPROC), though you wouldn't want to do that from a TRIGGER.
Oracle also provides "fine grained auditing". The information gathered by FGA is not at a "row by row" level, like we can get with a FOR EACH ROW trigger.
So, it really depends on what you are trying to achieve.
The next step is figuring out how you are going to get this information to your external process. Is that process going to periodically poll table (or set of tables), are you going to use AQ Advanced Queueing, or some other queue mechanism.

Database Loading batch job Java

Have a batch job written in Java which truncates and then loads certain table in Oracle database every few minutes. There are reports generated on web pages based on the data in the table. Am wondering of a good way of not affecting the report querying part when the data loading process is happeneing so that the users won't end up with some and/or no data.
If you process all your SQL statements inside a single transaction there will be always a valid state seen from outside. Beware that TRUNCATE doe not work in transactions, so you have to use DELETE. While this guarantees to always have reasonable data in your table it needs a bigger rollback segment and will be considerably slower.
you could have 2 tables and a meta table which tracks which table is the main table being used for querying. your batch job will be truncating and loading one of the table and you can switch the main tables once the loading is completed. so the query app will get recent data now and u can load now in the other table
What I would do is set a flag in a DB table to indicate that that the update is in progress and have the reports look for that flag and display an appropriate message and wait for the update to finish. Once the update is complete clear the flag.

database polling using Java

I am stuck at some point wherein I need to get database changes in a Java code. Request is to get any record updated, added, deleted in any table of db; should be recognized by Java program. How could it be implemented JMS? or a Java thread?
Update: Thanks guys for your support i am actually using Oracle as DB and Weblogic 10.3 workshop. Actually I want to get the updates from a table in which I have only read permission so guys what do you all suggest. I can't update the DB. Only thing I can do is just read the DB and if there is any change in the table I have to get the information/notification that certain data rows has been added/deleted or updated.
Unless the database can send a message to Java, you'll have to have a thread that polls.
A better, more efficient model would be one that fires events on changes. A database that has Java running inside (e.g., Oracle) could do it.
We do it by polling the DB using an EJB timer task. In essence, we have a status filed which we update when we have processed that row.
So the EJB timer thread calls a procedure that grabs rows which are flagged "un-treated".
Dirty, but also very simple and robust. Especially, after a crash or something, it can still pick up from where it crashed without too much complexity.
The disadvantage is the wasted load on the DB, and also response time will be limited (probably requires seconds).
We have accomplished this in our firm by adding triggers to database tables that call an executable to issue a Tib Rendezvous message, which is received by all interested Java applications.
However, the ideal way to do this IMHO is to be in complete control of all database writes at the application level, and to notify any interested parties at this point (via multi-cast, Tib, etc). In reality this isn't always possible where you have a number of disparate systems.
You're indeed dependent on whether the database in question supports it. You'll also need to take the overhead into account. Lot of inserts/updates also means a lot of notifications and your Java code has to handle them consistently, else it will bubble up.
If the datamodel allows it, just add an extra column which holds a timestamp which get updated on every insert/update. Most major DB's supports an auto-update of the column on every insert/update. I don't know which DB server you're using, so I'll give only a MySQL-targeted example:
CREATE TABLE mytable (
id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
somevalue VARCHAR(255) NOT NULL,
lastupdate TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX (lastupdate)
)
This way you don't need to worry about inserting/updating the lastupdate yourself. You can just do an INSERT INTO mytable (somevalue) VALUES (?) or UPDATE mytable SET somevalue = ? WHERE id = ? and the DB will do the magic.
After ensuring that the DB server's time and Java application's time are the same, you can just fire a background thread (using either Timer with TimerTask, or ScheduledExecutorService with Runnable or Callable) which does roughly this:
Date now = new Date();
statement = connection.prepareStatement("SELECT id FROM mytable WHERE lastupdate BETWEEN ? AND ?");
statement.setDate(1, this.lastTimeChecked);
statement.setDate(2, now);
resultSet = statement.executeQuery();
while (resultSet.next()) {
// Handle accordingly.
}
this.lastTimeChecked = now;
Update: as per the question update it turns out that you have no control over the DB. Well, then you don't have much good/efficient options. Either just refresh the entire list in Java memory with entire data from DB without checking/comparing for changes (probably the fastest way), or dynamically generate a SQL query based on the current data which excludes the current data from the results.
I assume that you're talking about a situation where anything can update a table. If for some reason you're instead talking about a situation where only the Java application will be updating the table that's different. If you're using Java only you can put this code in your DAO or EJB doing the update (it's much cleaner than using a trigger in this case).
An alternative way to do this is to funnel all database calls through a web service API, or perhaps a JMS API, which does the actual database calls. Processes could register there to get a notification of a database update.
We have a similar requirement. In our case we have a legacy system that we do not want to adversely impact performance on the existing transaction table.
Here's my proposal:
A new work table with pk to transaction and insert timestamp
A new audit table that has same columns as transaction table + audit columns
Trigger on transaction table to dump all insert/update/deletes to an audit table
Java process to poll the work table, join to the audit table, publish the event in question and delete from the work table.
Question is: What do you use for polling? Is quartz overkill? How can you scale back the polling frequency based on the current DB load?

Categories

Resources