views:

310

answers:

5

I'm asking for a suitable architecture for the following Java web application:

The goal is to build several web applications which all operate on the same data. Suppose a banking system in which account data can be accessed by different web applications; it can be accessed by customers (online banking), by service personal (mostly read) and by the account administration department (admin tool). These applications run as separate web applications on different machines but they use the same data and a set of common data manipulation and search queries.

A possible approach is to build a core application which fits the common needs of the clients, namely data storage, manipulation and search facilities. The clients can then call this core application to fulfill their requests. The requiremnt is the applications are build on top of a Wicket/Spring/Hibernate stack as WARs.

To get a picture, here are some of the possible approaches we thought of:

A The monolithic approach. Build one huge web application that fits all needs (this is not really an option)

B The API approach. Build a core database access API (JAR) for data access/manipulation. Each web application is build as a separate WAR which uses the API to access a database. There is no separate core application.

C RMI approach. The core application runs as a standalone application (possibly a WAR) and offers services via RMI (or HttpInvoker).

D WS approach. Just like C but replace RMI with Web Services

E OSGi approach. Build all the components as OSGi modules and which run in an OSGi container. Possibly use SpringSource dm Server or ModuleFusion. This approach was not an option for us for some reasons ...

Hope I could make clear the problem. We are just going the with option B, but I'm not very confident with it. What are your opinions? Any other solutions? What are the drawbacks of each solution?

Thanks Nick

+2  A: 

B, C, and D are all just different ways to accomplish the same thing.

My first thought would be to simply have all consumer code connecting to a common database. This is certainly doable, and would eliminate the code you don't want to place in the middle. The drawback, of course, is that if the schema changes, all consumers need to be updated.

Another solution you may want to consider is giving each consumer its own database, using some sort of replication to keep them in sync.

DannySmurf
I definitely think that a good database design is the better solution. Permits easily plugging many kinds of clients, the DB manages transactions and all that already and you can replicate to different schemas/db for different purposes.
Loki
I agree. But that requires full control over the database and its schema, something the original poster does not necessarily have.
DannySmurf
That was my first thought too--although I'd also consider a J2EE/JMS type solution if the transactions seemed to fit that model. Isn't this what J2EE is for?
Bill K
+3  A: 

I think that you have to go in the oppposite direction - from the bottom up. Of course, you have to go forth and back to verify that everything is playing, but here is the general direction:

Think about your data - DB scheme, how transactions are important (for example in banking systems everything is about transactions) etc.

Then define common access method - from set of stored procedures to distributed transaction engine...

Next step is a business logic/presentation - what could be generalized and what is a subject of customization.

And the final stage are the interfaces, visualisation and reports

Dmitry Khalatov
I agree. In banking, transactional integrity is business critical, and has to be designed into the architecture from the start. Other fields have much softer requirements and so a different architecture might be more appropriate.
Bill Michell
+1  A: 

I think you need to have a separate application that all the client applications will use as their data layer. The reason for this is that you want to ensure they're all accessing the database in the same way. There are also some race conditions you can get into that database transactions may not be able to prevent. The other reason is that using the database as a form of RPC is a known antipattern. If all your apps access the database directly, you will almost inevitably end up with some "event" table that the various applications poll periodically... don't do that.

rmeador
Why is this considered an antipattern? Is there any anecdotal publications on the web that consider it an antipattern ? Care to share some of them? Using SERIALIZABLE isolation level with AUTOCOMMIT off avoids race conditions.
ashitaka
A: 

Apart from the provided responses, if you are considering having multiple applications working with the database at the same time, consider a distributed cache as part of your solution, as well. The beauty of the distributed cache is that it can be accessed by multiple applications at the same time, apart from being distributed. I am not sure if this holds true for all of the Java variations, such as Ehcache, etc, as I do not come from a Java background.

What we are currently doing is abstracting the data a level further than before. We now have a DAL that can be accessed directly, but we have put a "Model Factory" in front of the DAL. The purpose of the Model Factory is to broker both the cache and the data layer, acting as a passthrough. So, the caller always calls the Model Factory and not the DAL or caching code directly. This abstraction layer will basically retrieve data from the DAL on a cache miss without adding the complexity to the API.

joseph.ferris
I like your idea. DAL = Database Access Layer ? I presume that is just a layer for DAOs ?
ashitaka
+2  A: 

It looks like A and E are out of the picture as you have stated in your question for various reasons. Option A would be one huge application which would make maintenance difficult in the future.

B, C and D are essentially the same architecturally since they involve remote access to common libraries from the various web applications, the only difference is the transport mechanism. I would recommend implementing this in EJB 3 or Spring if possible instead of with your own RMI libraries since either of these provide a good framework over RMI / Webservices.

So I think this problem basically boils down to the following two options:

1) Include the business and DAO layer classes as a common jar included in the deployment of all web applications.

Advantages:

  • Deployment is easier.
  • Applications will perform better initially since there is no remote access to other servers.

Disadvantages:

  • You cannot add more hardware to the middle tier specifically (service and DAO layers) since it is included in each web application.
  • Other business teams in the organisation will not have access to your business services since there is no remote interface.

2) Deploy the business service and DAO layer classes in a separate application server and expose business methods remotely.

Advantages:

  • You can scale up the business service and DAO layer as needed depending on load from the various web applications calling it.
  • Other applications in the organisation can make use of your interfaces if needed.
  • More scalable
  • You get all the advantages of JEE.

Disadvantages:

  • More complex deployment.
  • Another server to maintain and monitor.
  • Could be slower since calls will be made over the network although this shouldn't be too much of a problem.

In both cases if the interfaces change the client code will need to change so this isn't a factor in the decision. Transactions should be handled on the business service method level so this shouldn't be a factor either.

I think it depends on the size of the applications as well and how scalable the solution needs to be to warrant the extra complexity of option 2 above.

Neal Donnan