Prevent simultaneous DB Transactions on play2.1 application - java

I came across a serious issue with our payment workflow today.
Once a payment is completed, two things happen:
the user gets redirected to a success-page on our server, the redirect also appends the payment id
the payment provider sends a payment notification including the payment id to our server
When the user gets redirected to the success-page we check whether a payment with the payment id exists. If this is not the case we create a pending payment that we can show to him.
When the payment provider sends a payment notification we check whether there exists a pending payment with the payment id and set it to active, if no payment exists we just create an active one.
Here's the problem: Both events can (and did!) happen simultaniously such that both routines did not find an existing payment and so two payments got created. One pending and one active.
Is there a good way to circumvent this behaviour by possibly using locks or something?
I'm using the default Ebean ORM on a java based play 2.1.0 with a MySQL db.

This isn't a Play thing at all. My advice is to not use locks. If you do then you will limit the scalability of your application.
You need to cope with this race condition. Race conditions will always occur and there's nothing you can do to prevent them. So, embrace them.
In the instance you describe its sounds like the pending state should be overridden by the active state if both exist in the database.

I don't know if this answers your question or not, but here is a link to the Ebean transactions page.

Related

Spring boot JAVA - how to maintain user logging details and identify any API is not called for certain time interval specific to user

We are using Angular5 as front-end. Spring Boot JAVA for APIs. We would like to maintain logged in/logged out details of users like, when a user say user1 logged in(field loggedin in table is set as 1), and after logout (loggedin field value updating as 0).
This is working fine in normal scenario. In case, user closes the browser or closes the tab, at that time, API is not triggered so consequently, in table level also it is not updating.
Finally, we thought like, if no APIs are triggered for certain 5 minutes or certain time interval then we have planned to assume the user might logged out. So, we are trying to find out , like if no APIs are calling for last 5 minutes user-wise. How can we arrive it?
Actually, we are new to Spring Boot JAVA. Kindly guide us on this or any other idea or suggestions are greatly appreciated.
Thanks in advance.
I think you are using extra tags to track user activity, maybe you want to limit it to users current actions (like for logout, just update that logged out, as it would implicitly mean used not logged in anymore).
To achieve what you are looking, there is a session associated with every request, maybe new created or the existing one. You can keep a track of sessions created, and if any session is inactive for more than timeout time, you can destroy the session and while doing so, you can update the status of related tags at that step.

Data integrity in concurrent requests from a user to a Spring MVC Controller method

I was hoping to understand how one can ensure data integrity in case of concurrent requests from same user to the same Spring Controller method ?
for e.g.suppose in an Online shopping scenario,a user happens to make
concurrent requests to a Controller method
(e.g.'/debitWallet?amount=100' to deduct his wallet money). The
'Wallet' could be a hibernate entity which is obtained in this method
through a standard 'WalletService' instance -->'WalletDao' instance.
Now how can we ensure data integrity of the wallet for concurrent
requests?
On what objects do I synchronize here?
what would be the scope of different beans(service,dao etc.) although I don't see any way that would help since the Wallet is going to be taken from the data store?
Should I even take the Wallet from the DB every-time the Controller method is invoked.Would it be a right approach? Instead should I use #SessionAttribute on this Wallet entity & then use it for every request to this method?
I could really use some help here to understand how to tackle data-integrity issue in this use case?
First of all answer the question: how frequent will be your data changed?
If it is not so frequent (or your database iterations are fast) you can use pattern: "User always operates with recent wallet instance, which is constantly synchronized with database". And to make it work user always sends Optimistick lock value (#Version field on entity), and in case changes happened in background: user receives Optimistick locking exception.
If it is frequent you should deeply analyze your implementation and then - search places for synchronization. Or even rework your API.

How to check other user Session alive in Spring Framework

I have searched a lot on stackoverflow questions but I couldn't find the solution that fulfill my requirement; if any one known about reference that exactly match my requirement please comment otherwise answer it.
I am developing Enterprise application using Spring Framework in team, I have successfully integrate the "JMS" using ActiveMQ in application.
In this application User A send message to User B if user B is online otherwise not!
My Question is that how to check that User B session is live or not before user A message send to User B
Thanks In advance
Yasir Shabbir
it depends how you make communication with user B.
use web sockets to make push notifications to verify the status and push messages to user B.
client can regularly poll the server to get data if arrives from any user (in this case user A). if user B is online then only yhe polling can happen so it would be like user B gets a message from user A when he's online.
You need something that monitor the users http session.
The simple approach is to have a Map or Set. Put the usersId (or what ever you use to identify them) in that Map/Set when ever they login, also put hat Id in the Session. Then use a HttpSessionListener to get notified when ever a session get destroyed (that is the closest thing to SessionTimeOut you will get). When the Session gets destroyed the remove the userId from the Map/Set.
(BTW. there is a new Spring Project: Spring-Session, I did not have a look on it up to now. Maybe it contains support for that problem.)
An easy way if you have a small number of clients is to use request-reply over messaging in conjunction with topics. Have all user sessions listen to topic (pings or similar). When a client wants to see who is online, they send a message (the contents of the body don't matter) and set the JMSReplyTo and JMSCorrellationID headers to identify a temporary queue that they are listening to for replies. The listening parties will pick up this message and all send back a message containing their ids. That way you have a living cache on the sender as to who is currently "online", the cache should expire every couple of seconds.
Take a look at http://activemq.apache.org/how-should-i-implement-request-response-with-jms.html

How to implement shopping cart functionality when creating REST web service?

I am creating an app store for digital services. I want the user to be able to choose multiple products with different quantity before confirming the order and pay for the services. This requires that something keep state. From REST Wikipedia:
Each request from any client contains all the information necessary to service the request, and session state is held in the client.
I got state that I need to keep somewhere, and I also have a flow. The flow I can mange, but it is the state that I don't understand how and where I should store. The user may add several products to a shopping cart before checking out.
I have thought of a endpoint like this where you post a cart-item object each time you want something.
POST /shopping-cart
But I shouldn't use HTTP sessions if I understand it right? I have seen someone saying to store it in database but would you use a in memory database then? When should i flush the database if the user doesn't confirm and pay? I could need some input on what I should do to keep it simple and RESTful.
I am using Spring 4.x and Java EE for the record.
But I shouldn't use HTTP sessions if I understand it right?
Correct.
I have seen someone saying to store it in database but would you use a in memory database then?
You should keep in in a disk-storage database. This allows you to add nodes to your server without having to worry about routing all requests from one client to the same node.
When should i flush the database if the user doesn't confirm and pay?
That's a business decision.

Top use cases for using Sessions in Java web application

I've been always trying to avoid using Sessions. I've used spring security or other ways of having user logged in the application, which is I suppose the major use case for using Sessions.
But what are the other use cases ? Could you please make a list of those most important ones ? How come that I've been able to develop even complicated applications without using Sessions?
Is it because I'm using spring-mvc and using Sessions is practically not needed except the login stuff ?
EDIT: Guys this question was asking for use cases... Most of the answers explains what are sessions for. If we summarize some usecases, we can say for sure, when to use database or sessions for maintaining conversation state...
Don't you remember any concrete scenarios you needed sessions for? For past years :)
for instance some conversational state may become persistent after some point / event. In this case I'm using database from the beginning.
I think you can do anything you want without storing anything on a sessions.
I usually use the sessions to avoid having to pass state between the client and server (used id as an example) and when I don't want to send sensitive information to the client (even in encrypted form) as it might be a security problem.
Other ways of avoiding using the session are:
store some state on a database, e.g. shopping carts, instead of in the session, even if the cart is discarded after a certain amount of time.
store state in cookies e.g. for user customization
One use case when it's really useful to use the session is for conversations, although usually frameworks manage that behind scenes, and store the conversation in the session.
edit
Converstions (in my understanding) are something like wizards, in which you complete several forms in different pages and at the end you perform the action. e.g. in a checkout process, the user enters his name, shipping address and credit card details in different pages, but you want to submit the order just at the end, without storing any intermediate state in your DB.
By sensitive information I mean, imagine in the previous example, once the user sent his credit card details, you shouldn't return that information in any format (even encrypted) to the user. I know it's a bit paranoid, but that's security :).
In the ecommerce system i'm working on, there is an external system at the back-end which stores users' saved shipping and billing addresses. Our web app talks to it by making web service calls to retrieve those addresses. When we get the addresses, we store them in the session. That way, we only have to call the service once, when the user firsts looks at their addresses, and not every time we serve a page which needs address information. We have a time-to-live on the addresses, so if the addresses change (eg if the user telephones the customer service desk to change an address), we will eventually pick up the fresh ones.
It would be possible to store the addresses in our database, rather than in the session. But why would we? It's transient information which is already stored permanently somewhere else. The session is the ideal place for it.
Well in one sense your question is deep (what's SPECIAL about a session is worth knowing) and in another sense it's shallow (what can't I do if I don't use them turns out to be a somewhat odd question)
In the end a Session is merely (or could be) a ConcurrentHashMap (in fact it usually isn't that threadsafe) with a a key of unique session id passing as the cookie. You know why it's useful, but to answer you for use cases
clustering (this is how state gets distributed across nodes)
caching general state of the user and their objects (as opposed to reloading from db each time)
built in methods for sessionlisteners to watch when someone is timed out, or attributes change.
= used for by a lot of localization utilities
Can you do all this with a database or your own hashmap implementation/filter? Of course, there's nothing magical about Sessions. They are merely a convenient standard for having some objects follow a logged in user and be tied to the lifetime of that user's use of the application.
Why do you use Servlets? You could also implement your own socket level standard? The answer to that is using standard apis/implementations provides convenience and other libraries build upon them.
The cons are
you are reinventing the wheel and some code that has been time tested
you won't be able to use a lot of built in facilities for monitoring/managing/clustering/localizing etc.
Sessions are one way of maintaining conversational state across multiple requests (e.g. multiple stateless HTTP requests.)
There are other ways of implementing conversational state, for example, storing an authentication token or some suitable conversation id as a cookie and maintaining a store of conversation id to session state. (In essence, duplicating what the app server is doing when it provides sessions.)
That you haven't needed to use sessions means that your application either doesn't need conversational state or you've implemented it in a different way. For example, perhaps your application uses an authentication token (say a cookie) and persists all state changes to the database. With that kind of arrangement, there is no need for a conversation state.
Hi you can take an example of shopping cart because since Http is stateless protocol it does not maintain the status of the user who sends the request.
For e.g.
If one user sends a request to buy camera from say eBay and after some minutes another user sends a request to buy laptop.
But since http is stateless protocol so server is not able to separate the request send by the users and may it happen that the bill of the laptop may be given to first user.
So through session we can maintain a particular entity over the server side for a particular user.

Categories