Running DB2 java stored procedures in single process - java

It seems, that DB2 creates new process for each connection when running java stored procedures in it (for example, procedures, which are called from trigger on some table update event).
The question is: is any way for running all java stored procedures in single process, so we could share static values between them?

DB2 will force multi-process model execution of your stored procedures.
I would suggest you to just send your data to a message queue, and have an application listening to that queue handle the data and do the logging. Take a look at for example RabbitMQ, Apache ActiveMQ, or ZeroMQ.
This would be probably trivial to implement, but it requires usually that you have a daemon with your application logic running. This is true unless you configure the message queue product to spawn your application logic automatically - which is usually possible with message queue products but requires a bit more configuration.

Unfortunately, I have to give a negative answer to my own question.
According to this paper: Static and non-final variables in a Java routine exactly what I'd like to do is impossible.

Related

Java internal message queue /JMS

I have a web application i am rewriting that currently performs a large amount of audit data sql writes. Every step of user interaction results in a method being executed that writes some information to a database.
This has the potential to impact users by causing the interaction to stop due to database problems.
Ideally I want to move this is a message based approach where if data needs to be written it is fired off too a queue, where a consumer picks these up and writes them to the database. It is not essential data, and loss is acceptable if the server goes down.
I'm just a little confused if I should try and use an embedded JMS queue and broker, or a Java queue. Or something I'm not familiar with (suggestions?)
What is the best approach?
More info:
The app uses spring and is running on websphere 6. All message communication is local, it will not talk to another server.
I think logging with JMS is overkill, and especially if loggin is the only reason for using JMS.
Have a look at DBAppender, you can log directly to the database. If performance is your concern you can log asynchronously using Logback.
If you still want to go JMS way then Logback has JMS Queue & Topic appenders
A plain queue will suffice based on your description of the problem. You can have a fixed size queue and discard messages if it fills too quickly since you say they are not critical.
Things to consider:
Is this functionality required by other apps too, now or in the
future.
Are the rate of producing messages so huge that it can start
consuming lot of heap memory when large number of users are logged
in. Important if messages should not be lost.
I'm not sure if that is best practice inside a Java EE container however.
Since you already run on a WebSphere machine, you do have a JMS broker going (SIBus). The easiest way to kick off asynchronous things are to send JMS messages and have a MDB reading them off - and doing database insertions. You might have some issues spawning own threads in WebSphere can still utilise the initial context for JNDI resources.
In a non Java EE case, I would have used a something like a plain LinkedBlockingQueue or any blocking queue, and just have a thread polling that queue for new messages to insert into a database.
I would uses JMS queue only if there are different servers involved. So in your case I would do it in simple plain pure java with some Java queue.

Calling/Using JMS from PL/SQL

Is it possible to call/use JAVA Messaging Service (JMS) from PL/SQL?
I know we can call java from pl/SQL, but calling java is different from calling JMS Queues or JMS Topics, because JMS depends upon JNDI-resource naming and when we use JNDI based resources we first have to deploy them in some J2EE container and then use them. So calling JMS always involves deploying on some J2EE container and then utilizing its functionalities.
Coming back to my question as i mentioned earlier, i want to use JMS from PL/SQL and how it would handle the deployment & JNDI-based resources stuff..?
There are two issues in your question that need to be addressed separately:
JNDI
No, calling a JMS service does not depend on having a JNDI-resource nor you need to have the JMS client deployed in a container. The reason for using JNDI within a container is to avoid having configuration parameters hard-coded in your application code (by using a "directory" of named "things".)
For example, we use JNDI to get a connection pool from which to get a jdbc connection, but I could equally create a jdbc connection directly. The later is fine for testing or for a command-line utility, but it is certainly not fine for a general case (which is why we typically opt for the former, jndi-based option.)
With JMS, yep, you indeed need JNDI, but that doesn't mean your client needs to be in a EE container. Take a look at the JMS tutorial at the Oracle/Sun site, and check the simple examples section:
http://download.oracle.com/javaee/1.3/jms/tutorial/1_3_1-fcs/doc/client.html
IIRC, every example shows clients that can be run from the command line and where you simply pass the queue name and other parameters from the command line. It should be easy to retrofit that code so that you can load them up from a property file or as parameters in a function call.
Java in Store Procedures
Once you have a command-line client that can access the JMS queue you want to access to, you can retrofit that code so that it runs as a stored procedure. Yes, you can use Java to write stored procedures with Oracle...
... now, I think that is a horrible feature, one that is way too open to abuse. But, if you have a legitimate need to access a JMS provider from PL/SQL, this would be one way to go.
First, convert your command-line jms client into a stored procedure. Check the existing documentation on how to create java-based stored procedures with Oracle.
http://www.stanford.edu/dept/itss/docs/oracle/10g/java.101/b12021/storproc.htm
http://download.oracle.com/docs/cd/B10501_01/java.920/a96659.pdf
Then have your PL/SQL code call the stored procedure just as they would call any other stored proc or SQL statement. And voila.
Parting Thoughts
I've never done any of this, and there might be problems along the way. However, at least conceptually, it should be possible. At the very least you should be able to create a jms command-line utility that you can then convert into a java-based stored proc.
edit
Apparently Oracle has something called "Oracle Advanced Queueing" where you can access a JMS provider directly via PL/SQL.
http://www.akadia.com/services/ora_advanced_queueing.html
http://technology.amis.nl/blog/2384/enqueuing-aq-jms-text-message-from-plsql-on-oracle-xe
http://download.oracle.com/docs/cd/B10500_01/appdev.920/a96587/qintro.htm
Looks like a lot of reading and elbow grease involved, but it is certainly feasible (assuming you are using the right Oracle version.)
I might be updating an old thread, but I just successfully used JMS to send out messages from a PLJava trigger function. The one requirement that I never found written anywhere, is you have to load the jms broker jar files(I used activemq) in your database through pljava install function. Other procedures are same as this example.

Need help with java web app design to perform background tasks

I have a local web app that is installed on a desktop PC, and it needs to regularly sync with a remote server through web services.
I have a "transactions" table that stores transactions that have been processed locally and need to be sent to the remote server, and this table also contains transactions that have retrieved from the remote server (that have been processed remotely) and need to be peformed locally (they have been retrieved using a web service call)... The transactions are performed in time order to ensure they are processed in the right order.
An example of the type of transactions are "loans" and "returns" of items from a store, for example a video rental store. For example something may have been loaned locally and returned remotely or vice versa, or any sequence of loan/return events.
There is also other information that is retrieved from the remote server to update the local records.
When the user performs the tasks locally, I update the local db in real time and add the transaction to the table for background processing with the remote server.
What is the best approach for processing the background tasks. I have tried using a Thread that is created in a HTTPSessionListener, and using interrupt() when the session is removed, but I don't think that this is the safest approach. I have also tried using a session attribute as a locking mechanisim, but this also isn't the best approach.
I was also wondering how you know when a thread has completed it's run, as to avoid lunching another thread at the same time. Or whether a thread has ditched before completing.
I have come accross another suggestion, using the Quartz scheduler, I haven't read up on this approach in detail yet. I am going to puchase a copy of Java Concurrency in Practice, but I wanted some help with ideas for the best approach before I get stuck into it.
BTW I'm not using a web app framework.
Thanks.
Safest would be to create an applicationwide threadpool which is managed by the container. How to do that depends on the container used. If your container doesn't support it (e.g. Tomcat) or you want to be container-independent, then the basic approach would be to implement ServletContextListener, create the threadpool with help of Java 1.5 provided ExecutorService API on startup and kill the threadpool on shutdown. If you aren't on Java 1.5 yet or want more abstraction, then you can also use Spring's TaskExecutor
There was ever a Java EE proposal about concurrency utilities, but it has not yet made it into Java EE 6.
Related questions:
What is the recommend way of spawning threads from a servlet?
Background timer task in a JSP web application
Its better to go with Quartz Scheduling framework, because it has most of the features related to scheduling. It has facility to store jobs in Database, Concurrency handling,etc..
Please try this solution
Create a table,which stores some flag like 'Y' or 'N' mapped to some identifiable field with default value as 'N'
Schedule a job for each return while giving loand it self,which executes if flag is 'Y'
On returning change the flag to 'N',which then fires the process which you wanted to do

How do I monitor a database for new entries?

I have an application solution which is made up of a web app written in Python (using Django framework) and a Java application which runs on the server.
The web application receives data and stores it into a database queue. The Java application is then to process the received data and also store the results in a database.
My question is how can the Java application be notified that there is new data in the database? Right now, it seems like I will have to regularly poll the database for new data. Is there any way around this?
PS. I have considered running the web app using Jython and using the Observer pattern but my host does not support Servlets.
Unless the database specifically supports it, polling is the only option I know of.
However, if your concern is load on the Java server, you could have another server that does nothing but polls for changes and then notifies your Java server when changes have occurred. I don't know if that is any better than doing a simple polling from the Java server (not knowing your specific problem space and hardware constraints).
Hope that helps.
Edit: after reading your statement again, it seems like you are already doing a messaging like framework (with the queue in the java application) so the database change could simply be another message that goes into the queue. If it needs priority, you could give the messages priority marks so that they get processed when they need to be processed.

Best approach to consume, messaging, and save audit data from Application A in Application B real time

My initial approach to this was to use a stored procedure in database of Application A, triggered on an insert to gather additional data and call a web-service, hosted by Application B to do the necessary mapping and persistence there. Application A and Application B may not be on the same machine. The initial requirement is to support a SQL Server database on Application A's side. A CLR stored procedure came to mind. However, it was felt that calling out to a web-service would have both severe performance implications in the SQL Server engine and also require elevation of permissions for the procedure that DBA's do not like to give.
I am now thinking in terms of the procedure creating some form of reference table on database A and a polling application consuming this data and cleaning up once processed at Application B. However, I cannot but think that there is a better way of doing this beside polling for the data.
Application A is Windows only. Application B could be Windows, UNIX, or LINUX, so Java would be the obvious choice on this side.
You've given us a list of approaches you've considered but you haven't really outlined exactly what it is you are trying to accomplish, what your goals are, etc., other than the one-sentence title of this question. Can you clarify exactly what your requirements are?
The standard answer for asynchronous messaging between applications is to use JMS. Application A places messages onto a queue whenever events that should be audited occur within it, and Application B is written to consume messages from the queue at a certain rate (if you want "realtime", then you can poll the queue very often). Application B can then do whatever it needs to with these messages - write them to a database, sent them to another web service etc.
This way, the actions in Application A - what you want to audit - and the behavior of Application B - how you want to audit the messages - are completely de-coupled from one another. This allows you to change things on either side - audit new types of events, change the payload of the message, output the messages to somewhere else, etc. - without changing the other side.
It also allows you to scale both applications independently of the other - you can add more instances of A without affecting B, A can produce messages at a much higher rate than B consumes them, and A does not wait for B to finish consuming a message before it is able to respond to the user's actions.

Categories