Coordinated save in database and disk in java - java

In my task I need to save file on disk and update info about in database.
Exception can happen when saving file and when updating info in database.
Do exist some ready open source solutions for it or it need write from scratch?
Thanks.

There's XADisk which provides transactional access to file systems. From their web site:
XADisk (pronounced 'x-a-disk') enables transactional access to
existing file systems by providing APIs to perform file/directory
operations. With simple steps, it can be deployed over any JVM and can
then start serving all kinds of Java/JavaEE application running
anywhere.

In Java, enterprise transactions management is ruled by the JTA spec wich is used in Java EE.
JTA allows to create several TransactionManager with differents implementations (one for database, one for file) and make them work together to define a cross-transaction
I think this could be a way for you to do what you want
Outside of a container, there are possibility to integrate JTA. You should have a look at Spring or JBoss implementations
Look at this blog post for more information about Spring and transactions usage

The file system isn't directly supported by Java EE, but you could implement/ search for a resource adapter for the file system.
http://docs.oracle.com/javaee/6/tutorial/doc/gipgl.html
http://docs.oracle.com/javaee/6/tutorial/doc/giqjk.html

Related

Using Hibernate/JPA with multiple ClassLoaders to access multiple databases

Our application is a middle-tier application that provides a dozen or so front-end application with access to a couple dozen databases (and other data sources) on the back end.
We decided on using OSGi to separate the unrelated bits of code into separate bundles. This ensures proper code encapsulation and even allows for hot-swapping of specific bundles.
One advantage of this is that any code speaking to a specific database is isolated to a single bundle. It also allows us to simply drop in a new bundle for a new destination, and seamlessly integrates the new code. It also ensures that if a single back-end data source is down, that requests to other data sources are unaffected. One complication is that each of those bundles is loaded by a separate ClassLoader.
We'd like to start using JPA for our new destinations that we're building. Previously, we have been using JDBC directly to send SQL queries and updates.
We've looked into Hibernate 4, but it seems that it was built on the assumption that everything is loaded using a single ClassLoader. Switching between ClassLoaders for different bundles does not appear to be something it can handle consistently.
While it seems that Hibernate 5 may have corrected that issue, all the tutorials/documentation I've found for it gloss over the complexities of configuration. Most simply assume you are using a single application-level configuration file, which will not suit our needs at all.
So, my questions are:
Does Hibernate 5 properly handle connecting to multiple databases, with the configuration/POJos for each database loaded by a different ClassLoader?
How do we configure Hibernate to connect to multiple databases using multiple ClassLoaders?
Is there another JPA framework that might be better suited to our specific needs?
Hibernate is fine but for OSGi usage you also need an intermediary. In the OSGi specs this is defined by the OSGi JPA service spec. It defines how to connect to a JPA provider in OSGi without a hard reference to it.
This spec is implemented by Aries JPA. It also provides additional support for blueprint and declarative services. There is also Aries transaction control service that takes similar approach to supporting JPA and transactions in OSGi it also uses the core of Aries JPA but is a bit different in usage.
The last part you might need is pax-jdbc which allows to define a XA datasource just with configuration. The examples already use it.
To get started easily you can use Apache Karaf which has features for all of the above.
Aries JPA allows to use different databases in the same OSGi application.

What is a better way to change variable in runtime server?

We maintain our server once a week.
Sometimes, the customer wishes that we change some settings which is already cached in server.
My colleague always write some JSP code to change these settings which are stored in the memory.
Is it a good method to use this kind of methodology?
If our project is not a Web container, which tools can help me?
Usually, in my experience, the server configuration is not stored only in memory of server:
What happens that after a configuration change, the server has been restarted / just went down for some system reason?
What happens if you have more than one instance of the same server to work on (a cluster of servers in other words)?
So, usually, people opt for various "externalized configuration" options that can range from "file-based" configuration + redeploy the whole cluster upon each configuration change, to configuration management servers (like Consul, etc.d, etc). There are also some solutions that came from (and used in) a java world: Apache Zookeeper, Spring cloud config server to name a few, there are others. In addition, sometimes, it's convenient to store the configurations in a database.
Now to your question: If your project is not a web container and you don't care that configuration will "disappear" after a server restart and you're not running a distributed cluster of servers, then, using JSP indeed doesn't seem appropriate in this case.
Maybe you should take a look at JMX - Java management extensions, that have a built-in solution so that you probably will be able to get rid of a web container (which seems to be not used by your team anyway other than for JSP modifications that you've described).
You basically need in memory cache, there are multiple solutions found in answers which include creating your own implementation or using existing java library. You can also get data from database and add cache over the database layer.

How to hold data for jar as library with cluster awareness

I am creating a library (java jar file ) to provide a solution of a problem. Library is mainly targeted for web application (j2ee application) can be used with spring and other framework.
Targeted j2ee application will be deployed in clustered environment.User will use this library by adding it in application class path.
Library has a dependency of some configuration which is packaged itself in library (jar) which will be used at run time.
At run time configuration can be modified.
As it is targeted for clustered environment, In case of any modification to configuration , updated configuration must be replicated to all of nodes of clustered environment.
As per my understanding there can be two ways to hold configuration to use at run time (I am not sure correct me if I am wrong)
1.Store configuration in file
2.Store configuration in database
In first approach (store configuration in file)
There will a property file in library to hold initial configuration .
At server start up time configuration from property file will be copied to some file (abc.xml) at server physical location.
There will be set of APIs to perform CRUD action in abc.xml file from user home location.
And every time abc.xml file will be used.
In this approach holding data is possible but for clustered environment I am not getting how it will update all the nodes of cluster in case of modification.
In second appraoch (store configuration in database table)
While publishing toolkit (jar file) sql table queries also published with jar.
User have to create table using that queries.
There will a property file in library to hold initial configuration .
At server start up time configuration from property file will be copied to database.
There will be set of APIs to perform CRUD action on database.
As there is any modification to configuration all nodes of cluster can updated with latest data using some third party tool (Hazel cast or any thing else.)
In analysis I found Quartz uses database approach to hold its configuration.
So when one download quartz distribution, it also have sql queries to create required tables in database, that will be used by quartz it self.
I want to know what are the standard design pratices to hold configuration in library (jar) form and what are the factor need to be noticed in such cases.
There are other solutions as well. Use a cluster aware caching technologies like EhCache or Apache JCS or Hazelcast. Use the cache API to retrieve configuration data from the library. You could add in a listener within your library to poll on to the configuration file and update the cache.
If you are planning to use solution 1 which you mentioned, you could set up a listener within your library which listens to the configuration file and updates the server copy whenever there is a change. Similarly for Solution 2 as well but if I were in your similar situation, I would rather use a caching technology for frequently accessed data(configurations). The advantage it would give me is that I would not have to update the configuration in all the nodes because it self replicates.

EJB and working with binary files - best practice

We have two ways of keeping files - database or filesystem.
So I have EJB, that can be connected to as from servlet as from java application.
The problem is with working with binary files. I found here that it's a restriction for EJB (NOT FOR OTHER JAVA EE CONTAINERS) to write/read files to/from filesystem. They say keep in database.
Ok. I said. But here and here everybody says that's a very bad idea. And I totally agree with it.
Another solution is JCR in Apache Jackrabbit implementation. But I consider it as both of ways. Here it says it keeps files also in filesystem.
So what is the best practice? Why can't we write files to filesystem without JCR?
You could use a JCA connector to access the filesystem from your EJBs. Thus the filesystem would be a resource http://code.google.com/p/txfs/ for a basic filesystem access.
XADisk for a more complete and transactional access.
Nuxeo doesn't use JCR anymore and you have also Modeshape ( JBoss/ RedHat implementation) on top of Infinispan as a data grid.
Keeping the binary files on the file system will have the least overall performance impact and that's the most appropriate way to go (applications managing tons of binary content like Alfresco use the file system and that works fine for them). If you need your files to be accessed from multiple servers you could store them on a single server and share the directory on the network or just use NAS. However working with the file system is not transactional but if that is critical you may use tools like XADisk that support transactions on a file system level.
JCR is also a good way to go but it is not meant to store only binary files, it's meant to store a "content" (binary data + metadata describing the binary data) in a hierarchical way. However using JCR you are adding another level of abstraction and that may have a performance impact. As the most popular JCR implementations like Apache Jackrabbit, Alfresco and Nuxeo use the file system behind the scene you should consider if you really need the additional features that JCR provides like metadata, versioning, thumbnails, document preview, etc. but with a performance penalty and integration cost or you can just go with the file system if it satisfy your needs.

How to manage transaction for database and file system in Java EE environment?

I store file’s attributes (size, update time…) in database. So the problem is how to manage transaction for database and file.
In a Java EE environment, JTA is just able to manage database transaction.
In case, updating database is successful but file operation fails, should I write file-rollback method for this? Moreover, file operation in EJB container violates EJB spec.
What’s your opinion?
Access to external resources such as a file system should ideally go through a JCA connector. Though there are several posts around discussing this, I never found a ready-to-use JCA connector for transactional access to the file system, so I started to write one:
Have a look at: JCA connector: a file system adapter. It's fairly basic, but manages commit/rollback of files.
Regarding other projects:
I don't know the exact status of commons-transactions, it seems dead to me.
Have a look at JBoss Transactional File I/O, looks promising.
Have also a look at Filera: File resource adapter, but I don't think it's transactional
Note that as soon as you have more than one transactional participant, the app. server really need to use distributed transaction and things get more complicated. You must not underestimate this complexity (e.g. database have another timeout mechanism for distributed transaction).
Another lightweight approach to consider is to use a SFSB that writes on the file system. If you implement SessionSynchronization interface, you get beforeCompletion and afterCompletion callbacks. The later indicates whether the transaction was committed or rolled back and you do cleanup if necessary. You can then implement a transactional behavior.
JTA is not simply for Databases, it can be used long with any other resource if that resource supports XA transaction. For example, XADisk enables one such integration of file-systems with XA transactions. Hence, it can also solve the problem of file-system and database consistency which you have been trying to solve.
Hope that helps.
Nitin
manually. You'll probably need to write compensatory transactions for this.
Maybe have a look at commons-transaction for transactional file access. Refer to:
Transactional File System in Java
An XA Filesystem
An XA Filesystem, update
In any case, you'll have to write files outside the EJB container or to interact with a JCA connector as pointed out by #ewernli.

Categories

Resources