I have to implement a number of activities (for example, update a user's profile, transfer points from one user to another, etc...), each of which can be composed by one or more logical steps (check if user has enough points, subtract points from the first user, check if the other user can receive then, credit these points to the second user) in a given order. I also need to implement some kind of "rollback" mechanism so that I can undo any previous steps if something goes wrong with step N (kind of what one usually foods in database transactions, except for the fact that a database may or may not be involved).
Are there any Java libraries which can help me with this? I've had a look at Drools but it seems overly complex. Also, I'm not sure it supports this kind of rollback mechanism. Any ideas?
The JTA specifications is a framework defining a standard behavior for java transactions.
A typical and well known use case is the simple database transaction, but JTA is far more generic. It's a framework to manage transaction over one or more transactional resource. A transactional resource can be a database of course, but it can also be a file, a messaging service, ...
If you have multiple transactionnal resources implied in one transaction, you must search for a JTA implementation supporting XA-Transactions.(and here is another interesting link about XA)
I don't say that this is a simple framework... but the problem you are facing is not simple at all.
If you've got to integrate with other services/providers through REST/SOAP/EJBs/etc. then I recommend looking at Apache Camel. Camel is an integration service that can integrate with pretty much every service or protocol out there. And, I believe, it supports rudimentary transactions. You can make a single service call and Camel will handle the routing and integration with whatever backend services you define. And, you can chain them. So, your flow would look like this:
Client makes call to service 'FOO'...
'FOO' is defined as a route that makes a REST call to '/bar', followed by an EJB call to 'MyService', followed by persisting the results to a SQL database, and then lastly calling a SOAP web service. The client then gets back the return value from this call, which can be whatever transformation or permutation of these calls you want. It's completely transparent to the client where the result came from.
Related
To understand if the spring events fits the task im working on I need to understand how they work, where are they stored?
as I can guess they are stored in a spring application context and disappears if the application crashes, is my guess correct?
Spring events are intended to use when calling methods directly would create too much coupling. If you need to track events for auditing or replay purposes you have to save the events yourself. Based on your comments, there are many ways to achieve this, based on the topology and purpose of the application (list not complete):
Model entities that represent the events and store them in a repository
Incorporate a message broker such as Kafka that support message persistence
Install an in-memory cache such as Hazelcast
Use a cloud message service such as AWS SQS
Lastly, please make sure that you carefully evaluate which options suits your needs best. Options 2 to 4 all introduce heavy complexity and distributed applications can bring sorrow and misery to your life. Go for the simplest option if you can and only resort the other options if absolutely necessary.
I have a requirement to migrate a legacy CORBA system to any latest java technology. The main problem I am facing is to provide long lived transaction(db) in the proposed system. Currently the client(Swing App) retain the CORBA service object and perform multiple db txn before actually committing/rolling back all the txn. Service layer keep the state of connection object through out to complete transaction.
I wanted to reproduce this mechanism in my new system(REST/WS) so that either Swing client/Web(future) can work in the same as is.
eg:
try {
service1.updateXXData(); // --> insert in to table XX
service2.updateUUData() //--> insert in to table UU
service1.updateZZData(); // --> insert in to table ZZ
service2.updateAAData(); // --> insert in to table AA
service1.commit(); // con.commmit();
service2.commit(); // con.commmit();
}
exception(){
service1.rollback(); // con.rollback();
service2.rollback(); // con.rollback();
}
Now I wanted to migrate CORBA to any modern technolgy, but still I am at large to find a solution for this. ( the concern is client do not want to make any change to service layer or db layer) , they just wanted to remove CORBA.
couple of options available for me are
Migrate CORBA to RMI --> so that changes required to current system are minimal, but transaction management,connection pooling, retaining state need to do my self.
Migrate CORBA to Stateful EJB --> Compare RMI more changes required, but better since I can use container managed connection pooling, maintain state in a better way.
Migrate CORBA to Stateful Webservice(SOAP) --> More futuristic, but lot of changes required - How ever I can convert IDL to WSDL, and delegate the call to implementation layer
Migrate CORBA to REST --> Most desired if possible - but the amount of time required to migrate is huge , Code changes would require from UI layer to service layer.
Thank you very much in advance
The order in which I would choose the options, from best to worst, would be 4, 3, 2, and 1, however I'd avoid stateful beans or services if humanly possible to do so.
I'll go over the implementation details of what you'll have to do in detail.
For any of these solutions, you'll have to use XA-compliant data sources and transactions so you can guarantee ACID compliance, preferably from an application server so you don't have to generate the transaction yourself. This should be an improvement from your existing application as it almost certainly can't guarantee that, but be advised that in my experience, people put loads of hacks in to essentially reinvent JTA, so watch out for that.
For 4, you'll want to use container-managed transactions with XA. You might do this by injecting a #PersistenceContext backed by a JTA connection. Yes, this costs a ton of time, testing, and effort, but it has two bonuses: First, moving to the web will be a lot easier, and it sounds like that time is coming. Second, those that come after you are more likely to be well-versed in newer web service technologies than bare CORBA and RMI.
For 3, you'll also want to use container-managed transactions with XA. SOAP would not be my first choice as it uses very verbose messages and REST is more popular, but it could be done. If it's stateful, though, you'll have to use bean-managed transactions instead and then hang on to resources across web service calls. This is dangerous, as it could potentially deadlock the whole system.
For 2, you can go two ways, either using container-managed transactions with XA by using a stateless session facade for a stateful EJB. You can use a client JAR for your EJB and package that with the Swing app. Using the stateless facade is preferable, as it will reduce the load on your application server. Keep in mind that you can generate web services from stateless EJB beans too, essentially turning this into #3.
For 1... well, good luck. It is possible to use RMI to interface with EJB's, and generate your own stub and tie, though this is not recommended, and for very good reason. This hasn't been a popular practice for years, may require the stubs and ties to be regenerated periodically, and may require an understanding of the low-level functions of the app server. Even here, you'll want XA transactions. You don't want to handle the transaction management yourself, if possible.
Ultimately, as I'm sure everyone will agree, the choice is yours on what to do, and there's no "right" or "wrong" way, despite the opinions stated above. If it were me (and it's not), I'd ask two important questions of myself and my customer:
Is this for a contract or temporary engagement, and if so what is the term? Do I get first pick at another contract for this same system later when they want additional updates? (In other words, how much money am I going to get out of this vs. how much time am I spending? If it's going to be a long term, then I would go with 4 or 3, otherwise 3 or 2 would be better.)
Why get rid of CORBA? "Because it's old" is an honest answer, but what's the impetus of getting rid of the "old hotness?" Do they plan on expanding usage of this system in the future? Is there some license about to expire and they just want to keep the lights on? Is it because they don't want to dump this on some younger programmer who might not know how to deal with low-level stuff like this? What do you want the system to do in two years, five years, or longer?
(OK, so that's more than two questions :D)
I have quite a simple problem. I am rewriting very old app which is using direct access to database through DAO objects. There is no business layer (the code is not mine and is quite anti-code), so connection.setAutoCommit(false) is used for starting the transactions everywhere in the code. I had to rewrite the project because of security reasons, so it does not use database connection but webservices and hibernate/jpa on the J2EE server side (before it was standalone app, now app+j2ee). Simple - I just moved the DAO/VO objects to the webservice server and rewrote sql to hql and DAO in client replaced with webservice client.
But what to do with transaction code? Normally one transaction one webservice call. So I need some mechanism (parameter in webservices?) that could help me to reference to the same hibernate transaction across multiple webservice calls. Is it completely bad approach and should I just move the transactions in server code?
I think you should use SessionBeans expose as JAX-RS services, and let them control the transactions.
If you need to have a transaction accross multiple webservice calls, just define a new webservice, also a EJB SessionBean that acts as a facade for the other calls.
I think is a bad practice to implement what you suggest (with referecing the same hibernate transaction), and I think it might not even be possible. Each WS call is a separate thread, at different moment in times, mixing transactions across threads is not a good practice.
I also think this is bad practice, because you usually build webservice methods that are coarse grained. So usually you are fine with one request per transaction.
I can understand your need but think about the downsides:
How will you do a rollback about several transactions? This will introduce data inconsistencies, if not possible.
If this is possible, your webservice won't be stateless anymore,
which is commonly considered bad practice.
This means, your API requests will be dependent on each other, so you have prerequisites for executing any of your request.
Have you tried to put your transaction within one request? This might help to re-structure and possibly enhance the code of your app.
I have 2 REST apis where I "persist" data, in a "transaction". I'm curious to hear suggestions on how to ensure that if the 2nd one has trouble the first one could be "rolled back".
I currently have a retry loop and if that fails I send a delete to the first call.
It works fine, I was just curious if it is possible to use spring transactions to handle this.
For that matter, are there other options?
It would be very interesting and useful if something like this was possible, but I don't think it could be possible since there is no standard API for commits/rollbacks with REST APIs as there is with the JDBC API. With Spring, you could never simply mark a method as #Transactional since Spring would have no idea how to "roll back" anything you did over a REST call without having to explicitly state it.
Are there any recommendations, best practices or good articles on providing integration hooks ?
Let's say I'm developing a web based ordering system. Eventually I'd like my client to be able to write some code, packaged it into a jar, dump it into the classpath, and it would change the way the software behaves.
For example, if an order comes in, the code
1. may send an email or sms
2. may write some additional data into the database
3. may change data in the database, or decide that the order should not be saved into the database (cancel the data save)
Point 3 is quite dangerous since it interferes too much with data integrity, but if we want integration to be that flexible, is it doable ?
Options so far
1. provide hooks for specific actions, e.g. if this and that occurs, call this method, client will write implementation for that method, this is too rigid though
2. mechanism similar to servlet filters, there is code before the actual action is executed and code after, not quite sure how this could be designed though
We're using Struts2 if that matters.
This integration must be able to detect a "state change", not just the "end state" after the core action executes.
For example if an order changes state from In Progress to Paid, then it will do something, but if it changes from Draft to Paid, it should not do anything.The core action in this case would be loading the order object from the database, changing the state to Paid, and saving it again (or doing an sql update).
Many options, including:
Workflow tool
AOP
Messaging
DB-layer hooks
The easiest (for me at the time) was a message-based approach. I did a sort-of ad-hoc thing using Struts 2 interceptors, but a cleaner approach would use Spring and/or JMS.
As long as the relevant information is contained in the message, it's pretty much completely open-ended. Having a system accessible via services/etc. means the messages can tap back in to the main app in ways you haven't anticipated.
If you want this to work without system restarts, another option would be to implement handlers in a dynamic language (e.g., Groovy). Functionality can be stored in a DB. Using a Spring factory makes this pretty fun and reduces some of the complexity of a message-based approach.
One issue with a synchronous approach, however, is if a handler deadlocks or takes a long time; it can impact that thread at the least, or the system as a whole under some circumstances.