Lock a particular method in java - java

In my java webappication, there is an action which updates the order object and saves it in DB through ajax call(POST request).
Method saveOrder() performs this action,
if multiple users perform the same action, there should be lock on this method, so that the write transaction is performed with the latest data.
The class file code is as follows
public class OrderLoader extends JSONProcessSimple {
#override
public JSONObject exec(JSONObject jsonsent) throws JSONException, ServletException {
JSONObject result = this.saveOrder(array);
return result;
}
public JSONObject saveOrder(JSONArray jsonarray) throws JSONException {
JSONObject jsonResponse = new JSONObject();
//Write operation on DB
return jsonResponse;
}
}
Is it possible through synchronized approach, please suggest me a solution.
Thanks in advance!

Depending on the architecture of your application (does it run in mutiple parallel instances in a clustered environment?), there is no simple solution; if it is executed in only one VM, synchronized could be an approach. Also, have a look at the java.util.concurrent.lock package.
For a more sophisticated, distributed approach, you could implement a DB-based lock.

A better solution would be to check your database isolation and your SQL. Perhaps you need a SERIALZIABLE connection or a transaction manager. That's server side.
It's easy to add a synchronized keyword, but I think it's more than that.
http://docs.oracle.com/javase/tutorial/jdbc/basics/transactions.html
http://www.precisejava.com/javaperf/j2ee/JDBC.htm

Synchronization allone would not do the job since you'd block until the first request is saved and then you'd still have to check whether the other orders are newer or not.
As the others already stated, there's no easy solution and it would depend on your architecturea and environment.
You might want to try some optimitistic locking approach, i.e. each update checks a version column and increments it if the version matches. Something like ... SET version = x + 1 WHERE version = x and then you check whether columns have been updated or not.
That would not get the latest order to be saved but would prevent lost updates. You could, however, adapt that approach to only update the database whenever you have newer data (maybe based on some date and then use WHERE date > x).
EDIT:
Since you're using Hibernate, I'd look into Hibernate's optimistic locking. That would at least handle concurrent edits since only the first one would succeed. If non-concurrent edits result in OptimisticLockExceptions you are probably missing a (re)read somewhere.
With concurrent edit I mean user A reads the object, changes it and then triggers the write. In between user B has also read the object and triggers a write later. The writes are not concurrent but user B didn't see the changes of user A and thus might result in lost updates.
In your case it would depend on what operations are done on an order. In some cases you might safely reread the order just before persisting the changes (e.g. when adding positions, it might even be ok to do so when deleting them - if the position doesn't exist you just do nothing) while in other cases you might want to report the concurrent edit (e.g. when two users edit the quantity of the same position, the order header etc.)

If your method updates order for different users then you dont need to have any synchronization as every thread hitting the method will have its own copy, thus its not a concern.
But if all users are acting on same data, you can use write to db in begintransaction and endtransaction. This should make concurrent writes threadsafe.

Related

A good strategy/solution for concurrency with hibernate's optimistic/pessimistic locking

Let's presume that we have an application "mail client" and a front-end for it.
If a user is typing a message or editing the subject or whatever, a rest call is made to update whatever the user was changing (e.g. the receivers) to keep the message in DRAFT. So a lot PUT's are happening to save the message. When closing the window, an update of every editable field happens at the same time. Hibernate can't handle this concurrency: Each of those calls retrieve the message, edit their own fields and try to save the message again, while the other call already changed it.
I know I can add a rest call to save all fields at the same time, but I was wondering if there is a cleaner solution, or a decent strategy to handle such cases (like for example only updating one field or some merge strategy if the object has already changed)
Thanks in advance!
The easiest solutions here would be to tweak the UI to either
Submit a single rest call during email submission that does all the tasks necessary.
Serialize the rest calls so they're chained rather than firing concurrently.
The concern I have here is that this will snowball at some point and become a bigger concurrency problem as more users are interacting with the application. Consider for the moment the potential number of concurrent rest calls your web infrastructure will have to support alone when you're faced with a 100, 500, 1000, or even 10000 or more concurrent users.
Does it really make sense to beef up the volume of servers to handle that load when the load itself is a product of a design flaw in the first place?
Hibernate is designed to handle locking through two mechanisms, optimistic and pessimistic.
Optimistic Way
Read the entity from the data store.
Cache a copy of the fields you're going to modify in temporary variables.
Modify the field or fields based on your PUT operation.
Attempt to merge the changes.
If save succeeds, you're done.
Should an OptimisticLockException occur, refresh the entity state from data store.
Compare cached values to the fields you must change.
If values differ, you can assert or throw an exception
If they don't differ, go back to 4.
The beautiful part of the optimistic approach is you avoid any form of deadlock happening, particularly if you're allowing multiple tables to be read and locked separately.
While you can use pessimistic lock options, optimistic locking is generally the best accepted way to handle concurrent operations as it has the least concurrency contention and performance impact.

How should I handle deletion of objects in Object Relational Mapping

I have had this confusion about how I handle the different lifecycle events of an Object where they are persisted in a database. I know this can vary with design, but I would like to know any standard / best practice which are followed in such cases.
Say I have a User class like this -
class User {
int id;
String name;
}
An object of this type represents a row in the database. The objects are accessed by multiple threads. So, how do you manage the object? What are its methods? How do you implement deletion of such an object?
Say there are two threads, A and B which are accessing the same user object.
// Thread A
User user = UserFactory.getUser(userId);
// Thread B
User user = UserFactory.getUser(userId)
user.delete(); // Or UserFactory.delete(userId)
Then what happens to the user object in thread A? Any clarification would be very helpful.
Thanks!
Then what happens to the user object in thread A? Any clarification would be very helpful.
Nothing. Of course that is probably your problem. What will happen if you try to persist in thread A after deletion is probably highly dependent on the ORM you are using but my guess assuming your using Hibernate is that it will fail trying to do an UPDATE/DELETE as the open Session in thread A does not know that the row is missing. This happens frequently.
Notice that thread A will always be able to mutate the user object freely with out error so long as it does not persist/delete. The error will only happen when you go persist/delete. In this case whoever is first persist/delete wins (no error).
People mitigate this problem in a variety of ways:
Silently swallow the exception and either reinsert the object or ignore
Promote the exception (usually an Optimistic Locking Exception) and convert to a user friendly error.
Never allow deletes in the first place. Use a boolean column to indicate delete.
Make your application implement Optimistic Locking in sync with your ORM's optimistic locking.
Use transactions and/or synchronized (single JVM)
Use transactions and row locking SELECT ... FOR UPDATE.
In most situations I go with number 2 and/or 3. Number 5 is the most pessimistic, requires lots of resources with the potential of dead locking.
from what I understand, as far as threads accessing an object, it is a free for all which means both of them may have access to the same object unless synchronization/locking is being used.
From what I am able to gather from your pseudo code, your deletion of the object would completely remove it from the system (including any threads that are accessing it), but I believe it depends on the way you delete it. If you delete an object within the thread itself, it should only delete it from that thread, but if you delete the object outside of the threads it should delete it from the entire system.
From what I see of your code, I am having trouble determining if you are trying to delete the object within Thread B or delete it in the rest of the code, but whichever you are trying to accomplish, I hope my above explanation helps.

Java Memory Storage to Reduce Database Load - Safe?

If I have a MySQL table that is not changed very often (once a month) which contains information such as active user accounts for a web service. How safe is it to do something like:
public AccountDao
{
List<Account> accounts;
/*fields*/
public AccountDao()
{
refreshAccounts();
}
public void refreshAccounts()
{
this.accounts = /*call to database to get list of accounts*/
}
public boolean isActiveAccount(String accountId)
{
//logic involving in memory list object above
}
}
I would do this because I have to check a user has an active account for every request to allow access to the web service. This would allow me to avoid one SQL call to the database layer (which is stressed at the moment) on every request. My question is how safe is it to store data like this in production?
By the way, I would refresh the account list whenever a new user account is added via an API call. As stated above, this would happen about once to twice a month.
Access to the shared state in the DAO (and potentially its callers) will need to be synchronized somehow to achieve thread safety.
Stale data can cause a wrong access decision. Since that is likely security relevant, your code will need to be bullet proof; in particular, it needs to work reliably in case of failures. This makes any notification based scheme shaky - what if the notification is lost?
Lifetime of credentials in memory is prolonged. Confidentiality can still be achieved by hashing the credentials (and frankly, if somebody can read your application's memory, you have many other problems). Manipulation of the password in memory requires the attacker to have access to heap memory, and if he can that, you've lost anyway, because he could just as easily change the database connection used for reading accounts.
That said, for a high-traffic webservice, caching credentials sounds like a sensible idea, but it's not totally trivial.
Edit: No, web containers don't synchronize threads. Concurrent requests will be served by concurrent threads, and if these happen to read and write the same data, that can cause a data race. For instance, one thread could read the list of accounts while it is being updated with new information, and thus see an incomplete list.
If you have some sort of trigger to update the in-memory object when the corresponding data base tables change then it should be safe.
Without a trigger it becomes a matter of correctness and, potentially, policy. What happens if different part of your infrastructure have different in-memory versions of the database?
How long an interval is acceptable between e.g. adding or removing a user and that change being reflected by your service?
Have a look at caching. Your libraries probably already support it, if not memcached is a good option.

hashmap cache in servlet

I am trying to implement a servlet for GPS monitoring and trying create simple cache, because i think that it will be faster then SQL request for every Http Request. simple scheme:
in the init() method, i reads one point for each vehicle into HashMap (vehicle id = key, location in json = value) . after that, some request try to read this points and some request try to update (one vehicle update one item). Of course I want to minimize synchronization so i read javadoc :
http://docs.oracle.com/javase/6/docs/api/java/util/HashMap.html
Note that this implementation is not synchronized. If multiple threads access a hash map concurrently, and at least one of the threads modifies the map structurally, it must be synchronized externally. (A structural modification is any operation that adds or deletes one or more mappings; merely changing the value associated with a key that an instance already contains is not a structural modification.)
If I am right, there is no any synchronization in my task, because i do only "not a structural modification == changing the value associated with a key that an instance already contains)". is it a correct statement?
Use the ConcurrentHashMap it doesn't use synchronization by locks, but by atomic operations.
Wrong. Adding an item to the hash map is a structural modification (and to implement a cache you must add items at some point).
Use java.util.concurrent.ConcurrentHashMap.
if all the entries are read into hashmap in init() and then only read/modified - then yes, all the other threads theoretically do not need to sync, though some problems might arise due to threads caching values, so ConcurrentHashMap would be better.
perhaps rather than implementing cache yourself, use a simple implementation found in Guava library
Caching is not an easy problem - but it is a known one. Before starting, I would carefully measure wheter you really do have a performance problem, and whether caching actually solve it. You may think it should, and you may be right. You may also be horrendously wrong depending on the situation ("Preemptive optimization is the root of all evil"), so measure.
This said, do not implement a cache yourself, use a library doing it for you. I have personnaly good experience with ehcache.
If I understand correctly, you have two types of request:
Read from cache
Write to cache (to update the value)
In this case, you may potentially try to write to the same map twice at the same time, which is what the docs are referring to.
If all requests go through the same piece of code (e.g. an update method which can only be called from one thread) you will not need synchronisation.
If your system is multi-threaded and you have more than one thread or piece of code that writes to the map, you will need to externally synchronise your map or use a ConcurrentHashMap.
For clarity, the reason you need synchronisation is that if you have two threads both trying to update the a JSON value for the same key, who wins? This is either left up to chance or causes exceptions or, worse, buggy behaviour.
Any time you modify the same element from two threads, you need to synchronise on that code or, better still, use a thread-safe version of the data structure if that is applicable.

Parallel updates to different entity properties

I'm using JDO to access Datastore entities. I'm currently running into issues because different processes access the same entities in parallel and I'm unsure how to go around solving this.
I have entities containing values and calculated values: (key, value1, value2, value3, calculated)
The calculation happens in a separate task queue.
The user can edit the values at any time.
If the values are updated, a new task is pushed to the queue that overwrite the old calculated value.
The problem I currently have is in the following scenario:
User creates entity
Task is started
User notices an error in his initial entry and quickly updates the entity
Task finishes based on the old data (from step 1) and overwrites the entire entity, also removing the newly entered values (from step 3)
User is not happy
So my questions:
Can I make the task fail on update in step 4? Wrapping the task in a transaction does not seem to solve this issue for all cases due to eventual consistency (or, quite possibly, my understanding of datastore transactions is just wrong)
Is using the low-level setProperty method the only way to update a single field of an entity and will this solve my problem?
If none of the above, what's the best way to deal with a use case like this
background:
At the moment, I don't mind trading performance for consistency. I will care about performance later.
This was my first AppEngine application, and because it was a learning process, it does not use some of the best practices. I'm well aware that, in hindsight, I should have thought longer and harder about my data schema. For instance, none of my entities use ancestor relationships where they would be appropriate. I come from a relational background and it shows.
I am planning a major refactoring, probably moving to Objectify, but in the meantime I have a few urgent issues that need to be solved ASAP. And I'd like to first fully understand the Datastore.
Obviously JDO comes with optimistic concurrency checking (should the user enable it) for transactions, which would prevent/reduce the chance of such things. Optimistic concurrency is equally applicable with relational datastores, so you likely know what it does.
Google's JDO plugin uses the low-level API setProperty() method obviously. The log even tells you what low level calls are made (in terms of PUT and GET). Moving to some other API will not on its own solve such problems.
Whenever you need to handle write conflicts in GAE, you almost always need transactions. However, it's not just as simple as "use a transaction":
First of all, make sure each logical unit of work can be defined in a transaction. There are limits to transactions; no queries without ancestors, only a certain number of entity groups can be accessed. You might find you need to do some extra work prior to the transaction starting (ie, lookup keys of entities that will participate in the transaction).
Make sure each unit of work is idempotent. This is critical. Some units of work are automatically idempotent, for example "set my email address to xyz". Some units of work are not automatically idempotent, for example "move $5 from account A to account B". You can make transactions idempotent by creating an entity before the transaction starts, then deleting the entity inside the transaction. Check for existence of the entity at the start of the transaction and simply return (completing the txn) if it's been deleted.
When you run a transaction, catch ConcurrentModificationException and retry the process in a loop. Now when any txn gets conflicted, it will simply retry until it succeeds.
The only bad thing about collisions here is that it slows the system down and wastes effort during retries. However, you will get at least one completed transaction per second (maybe a bit less if you have XG transactions) throughput.
Objectify4 handles the retries for you; just define your unit of work as a run() method and run it with ofy().transact(). Just make sure your work is idempotent.
The way I see it, you can either prevent the first task from updating the object because certain values have changed from when the task was first launched.
Or you can you embed the object's values within the task request so that the 2nd calc task will restore the object state with consistent value and calcuated members.

Categories