Hi please can anyone help me out on how to handle multiple transaction in spring. For example i am trying to register an user in my application. I have collected data from my UI layer.now i need to do the following activities
save the data into multiple tables in database.
need to send an email & sms to the user containing username and password
send an notification email to admin
update some other table value.
Now if something goes wrong in above 4 steps application should able to revert everything and display the error message.
How can I handle these task in spring??
You need to wrap your Database modification into a Service with #Transactional annotation and change the order about what you just said.
//This two step in the same service with #Transactional annotation.
1. save the data into multiple tables in database.
2. update some other table value.
//Once you save on database and everything it´s ok you can send emails without any problem since you dont have to rollback.
3. send an email & sms to the user containing username and password
4. send an notification email to admin
There is no way to treat email-sending as a transactional resource the same as a database! Once an email has been sent, it is difficult to call it back. In this field there simply is the infrastructure missing that provides all that handy transactional committal and rollback functionality that you get with databases.
Your best work-around is to send your emails after your database updates have been successfully committed. You can make your database updates transactional with Spring's DataSourceTransaction Manager and #Transaction or one of the other "two-thousand" ways of doing this with Spring.
To do the post-transaction committal sending of your email, check this question. Personally, I favor the idea to use a transaction after commit hook to send "email-trigger-messages" to a standalone Message Queue like HornetQ. That way, you can use the queue's out-off-the-box failover mechanism to ensure that your emails will definitely get be delivered.
Related
I am trying to listen for transactions for an account, I need to know when a transaction is received and get the hash of that transaction.
I am using Solana's json rpc api on https://api.testnet.solana.com
What I tried so far:
blockSubscribe: is unstable and disabled by default.
accountSubscribe: this will send the account balance but not the transaction.
logsSubscribe: tried passing account address as mentions but didn't work.
You need to use getConfirmedSignaturesForAddress2 then use getConfirmedTransaction to get the actual transaction.
Language: Spring Boot, JS
Overview: I am implementing server sent events functionality in my application which will be deployed in cloud foundry,
wherein based on a new message in a queue(which I have subscribed in my micro-service), I will send some update to my client/browser(which is using EventSource).
For this, I am maintaining a SseEmitters List(for mainitaining all the active SseEmitter) on my server side. Once I receive a new message from the queue, based on the id(a field in the queue message), I will emit the message to corresponding client.
PROBLEM: How will the above scenario work, when I scale my application by creating multiple instances of it. Since only one instance will receive the new queue message, it may happen that the active SseEmitter is not maintained in that particular instance, how do I solve this?
To solve this problem, following approaches can be observed.
DNS concept
If you think about it, knowing where your user (SSE Emitter) is, is like knowing where some website is. You can use DNS-look-alike protocol to figure out where your user is. Protocol would be as follows:
Whe user lands on any of your instances, associate user with that instance. Association can be done by either using external component, e.g. Redis or a distributed map solution like Hazelcast.
Whenever user disconnects from SSE, remove association. Sometimes disconnect is not registered properly with Spring SSEEmiter, so disassociation can be done when sendig message fails.
Other parties (microservices) can easily query Redis/Hazelcast to figure on which instance user is.
Message routing concept
If you're using messaging middleware for communication between your microservices, you can use routing feature which AMQP protocol provides. Protocol would be as follows:
each SSE instance creates their own queue on boot
user lands on any of SSE instances and instance adds exchange-queue binding with routing key = user uid
Whenever user disconnects from SSE, remove association. Sometimes disconnect is not registered properly with Spring SSEEmiter, so disassociation can be done when sendig message fails.
Other parties (microservices) need to send message to the exchange and define routing key. AMQP broker figures out which queue should receive message based on the routing key.
Bindings are not resource intesive on modern AMQP brokers like RabbitMQ.
Your question is old, and if you didnt figure this out by now, hope this helps.
I am facing a problem and hope that someone can give me some advice.
I have a restful Spring application which allows HTTP-requests. I am using spring security and offer oauth2. In my basic service, called by a controller, I am fetching the currently logged user via:
SecurityUser loggedUser = (SecurityUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
So far, that's all working fine. Furthermore, I am using events and event listeners implementing the org.springframework.context.ApplicationListener interface. I configured the application event multicaster the way that events are handled asynchronously (using a SimpleAsyncTaskExecutor).
The (obvious) problem arises when I try to use my service (and methods which rely on the currently logged user) in my listeners. They cannot access the context as they are working asynchronous. Hence, I cannot fetch the current user.
Can you give any advice how to solve the problem? Are there more options than to
save and extend the context somehow so that the async listeners can
still access it? if so, how to do it?
change all the services methods to hand over the user via a parameter
(instead of the service fetching the current user itself) and store
its id e.g. in the event.
Thank you very much. Myself
You can use a DelegatingSecurityContextAsyncTaskExecutor instead of a SimpleAsyncTaskExecutor. The problem is that you only can get the user's context when the user is logged.
I am pretty new to the REST world and we are trying our hands at migrating our application to a REST based architecture. We are working on a proof of concept and we need to come up with a working proof that what we are set to achieve can be done using REST.
In our architecture, the front end screens would use Angular and would call REST services to open up a customer session and perform/maintain transactions within that session and when the session is complete, the session details (i.e. all the customer transactions within the customer session) would be sent over for commit to the DB. We only want to write to the DB after customer completes all transactions within a session. In other words, a commit to the DB happens only when the session ends.
I am hoping to get some directions on how best to perform the below steps in our Java classes.
1) Browser initiates a request to open a new customer session. A session POST service is used to generate a new session ID. The session ID is sent back as response to the browser.
Question --> What is the best way to maintain this session ID value in my Java classes?
2) Customer transactions are performed within the session. For each transaction processed a transaction POST service is used to save the transaction information along with the session information.
Question --> In my Java classes what is the best way to maintain this transaction information and how best do I associate this transaction information with the session information that was created by the previous session POST information? The client would maintain the session ID but on the service side I need to be able to map the transaction with the session ID so that I can send back a combined session payload that includes session information and the transaction within that session.
3) A customer can perform some more transactions and each transaction performed would be a transaction POST request which would have to get associated with the session id created before. Each additional transaction performed would have to be associated to the session id on the service side such that when I do a GET on the session id, I need to get the session details along with all transactions within that session.
4) Finally when the session is complete the information from the session and the session payload on the service side (along with all the transactions) will commit to the DB.
I am just looking for some general guidance on how best to do this using my Java classes and Jersey REST.
Any pointers would be appreciated.
Thanks
Ali.
Basically this question isn't easy and requires a lot of writing, however I'll try to reply.
First of all remember that REST is stateless - it means that there's no session and client needs to be authorized with every request. This is a separate topic but a nice authorization method in REST is JSON Web Token.
Secondly REST is about nouns - not verbs. Thus you should avoid URLs like /session/{sessionId}/close/ but try to model the domain using nouns and default HTTP operations: POST (create), PUT (update), GET (read), DELETE (remove).
I guess that session and transactions is just an abstraction I will show you how to model it on an example of shopping cart. In all examples I doubled the URLs - with /users/{userId}/ prefix to show you can refer to resources in many different ways
Create a shopping cart (creating a session)
POST /shopping-carts/
POST /users/{userID}/shopping-carts/
Request: may be empty or should contain necessary details about the cart
Response: must contain a newly-created shoppingCartID
{
"shoppingCartID": "1qaz2wsx"
...
}
Add an item to a shopping cart (create a transaction)
POST /shopping-carts/{shoppingCartID}/items/
POST /users/{userID}/shopping-carts/{shoppingCartID}/items/
Request: contains details about an item being added
Response: returns a newly-added item along with its unique ID
Pay for the shopping cart (commit the transactions)
POST /payments/
POST /users/{userID}/payments/
Request: must contain a shoppingCartID
{
"shoppingCartID": "1qaz2wsx"
...
}
Response: Contains details about newly-created payment
{
"paymentId": "3edc4rfv"
...
}
I know that this is a general answer but it's difficult to give a precise answer for such a wide question.
EDIT (after a discussion in comments)
In my opinion the DB should be used to keep the transactions in a temporary table before they are approved. Even if you don't want to use a DB any other persistent store is highly recommended - imagine what could happen in case of a server restart when transactions are not approved, you will lose all the data.
The options I see:
In memory. You can write a simple in-memory structure with a synchronized access. In the most simple case just plain old HashMap will be enough. Mind the fact that keeping data this way is risky, the can be erased very easily.
Use file system. If you don't want to use DB you can use file system to keep the transactions data while they're uncommitted. After adding a new transaction it's written to a file. On commit file is read and all transactions are saved to DB. A synchronized file access is also very important here. When it comes to data format you can use JSON, XML, even plain java serialization.
The last idea that comes to my head is to use an in memory DB, such as Redis. The data will be erased on a system reboot so they're less likely to be deleted, however this is not safe in my opinion as well. Such DB is much easier to use/maintain than traditional DB.
It all depends what are you trying to implement. I can't imagine a scenario where uncommitted transactions can be simply removed and nothing happens - it seems that there's a must for persistent storage. However the ideas above might be useful as well.
I have a web app that uses a Java Bean for login functions right now and all of the JSP pages check the Bean to make sure the user is logged in. I am also introducing some AJAX functionality now with servlets and I see that of course those exchanges don't check authentication. I'm wondering how I should handle this. For example, I don't want someone to be able to logout, hit back button, then submit something with the AJAX functions successfully.
I can't access the bean from the servlet to check the login (totally wrong context and static vs non-static). I guess I could set a flag with the user entry in the database table denoting logged in or not. Then I can detect timeout logoffs and update the flag as well. But that way would require extra database accesses every time something is done. It would duplicate functionality in some way, but I guess I could perhaps use that just for the AJAX stuff. One difference with that would be the user would not be able to be logged in on multiple places at once as currently.
How is this kind of thing normally done?
Thanks for any help!
You could use session to store that flag instead of the database, and when the user logs out you should remove that flag and destroy the session. In login method
HttpSession session = req.getSession(true);
session.setAttribute("loggedIn",true)
And in your AJAX code
if(eq.getSession(true).getAttribute("loggedIn")==true)
doWork();
else
error("not logged in");
The webcontainer will handle timeouts for you, keep track of each user and his session, and so on.
But I would recommend that you use a standard for managing authntication