I am developing a Spring Application in which many users would access that application at a time, now the scenario is if one user hold the particular data from database the other user shouldn't access that particular data until it get release, like as Review in stack overflow, give some suggestion to solve this problem.
Create a DB objects cache in your app. When user 1 requests an object (eg by ID) you read it from db, place it in the cache, lock it and remember who locked it (there should be a lock and lockedByUser fields in the object) and return it to user 1. When user 2 requests the same object you block him until lock is released or throw an Exception. It's just a basic idea.
Related
I have a question about concurrent access in java.
The project context is as follows: JSF 2.1; Richfaces 4, hibernate 3.6, spring 3.2, java 7.
I have a table that displays hundreds of thousands of folders (each folder is a java object), each table line is a dynamic link to access the consultation or modification of the object(folder).
My question is: how can I prevent more than one user from viewing or editing a folder?
In other words, how do you detect access to a folder (object java) by more than one user at the same time?
I know that with the word Synchronized on methods makes it possible to prevent concurrent access, but I want to detect concurrent access to warn the other user or the other users that the folder (object java) is already open and we have to wait for it closed.
Thank you
Synchronization and all the other locking / blocking methods is only preventing concurrent access from within the code.
It does not prevent 2 users from editing the same "thing" at the same time. This is something you have to put into your code on your own.
There are two most common ways to achieve this:
Optimistic Locking:
You assume, that even if multiple users view the same item, there are not multiple changes at the same time. Hence, you only check during SAVING if there is a concurrent modification. To Achieve that:
The Object in Question needs a Timestamp, when it was last modified. (By anyone)
Once a user opens an item to view, you store that timestamp in the session context.
If the user clicks "save", you compare the session-context-timestamp with the timestamp of the actual object. If they are the same, changes can be saved. If the Object has been modified in between, you need to display an error, that it has been modified, and changes can't be saved without loading the new base-values prior.
Pessimistic Locking:
You assume, that whenever a user views an Object, that there will be a change. To Achieve that:
The Object in Question needs a Int-Flag, that it is currently beeing edited (By anyone - Flag = UserID)
Once a second user tries to load that object, you deny cause someone is editing currently.
Tricky part here is to clean up "locks", if the editing user just quits the page without "aborting" through application methods. To handle this, you need to define a Lock-Timestamp, define some timeout value (for example 30min) and do two more checks:
Editing user exceeded the timeout value upon save? he can't save anymore.
(As an extra you can allow later saving, if the object has not been locked by someone else in between, use the lock-user-id to figure out)
Object is locked, but lock is older than 30 minutes? Second User can open again, claiming the lock-user-id for himself.
I would like to understand how Firestore works for counting read operations.
firestore lecture operations
I have a database and an application for mobile devices so to make Firestore go offline, nothing needs to be done.
When my application is opened the user receives data from a collection of | n | documents.
I wanted to understand if a user who opens the application with the internet will perform read operations from the database even if there are no changes in the database?
Or every time it accesses if there are no changes, no read operations are added since the data still resides in the cache?
if a user who opens the application with the internet on will perform read operations from the database even if there are no changes in the database?
If you are using get() call, the Firestore SDK will always try to get the data from the server, no matter if the data is changed or not. You'll be able to use the data from the cache, only if the device goes offline. However, if you trying to listen for changes in real-time using a SnapShotListener, according to the official documentation:
The initial state can come from the server directly, or from a local cache. If there is a state available in a local cache, the query snapshot will be initially populated with the cached data, then updated with the server's data when the client has caught up with the server's state.
In other words, if the server says that you have no new added/updated/deleted documents, you get the data from the cache. However, there is something else you should take care regarding the duration of time you can get the data from cache:
Also, if the listener is disconnected for more than 30 minutes (for example, if the user goes offline), you will be charged for reads as if you had issued a brand-new query.
Another possible charge might also come from:
There is a minimum charge of one document read for each query that you perform, even if the query returns no results.
But all these charges are normal according to how is Firestore designed.
My aim is to built a trusted synchronization between both local DB and server DB with NO conflictions or deadlock.
I suppose that a user may request his transaction using DML (insert, update and delete) from his local DB where there is NO access to the Interent and when he wants he asks for sync and send all the transaction with the data i need to the server via RESTful API.
My problem when tow sync operations has performed in a different time and different user which may cause a conflict (ex. the first user update a row and the second user tries to update the same row but another column while they were both offline before sync operations).
In the local DB i track every transaction on another table for every type of transaction (inserted_table , updated_table and deleted_table) every one of them contain table_id,row_id and time.
My question when i send these information to the server for the first user when he asks for sync and then after while the second user makes sync too how i can know the information for the first sync process for the first user(like time of the transaction in the local for the first user) to make rollback if i need and how to mange the conflict resolution?
The whole synchronization logic is up to you to decide how it should work!
One solution to your problem is to add columns STATUS(varchar) and LASTMODIFICATION(datetime). When syncing the databases, you can choose the most recent by comparing the LASTMODIFICATION field and overwrite the data with the newest update.
I have a situation in my java, spring based web app. My server generates coupons ( a number mixed with alphabets , all random but unique) , each coupon can be applied or used by only one and only on logged in customer. They are shown on the front end to all the users, which then gets accepted/selected by the customers.But once accepted by one customer it gets assigned to him and not available to anyone else.
I tried to do synchronization of code block which checks if the coupon is already applied / availed, it worked but , cases like when two users click avail it at exact same time, it fails ( get allocated to both)
Please help.
Do not use synchronization for this. You can store the state of the coupons in a database, and work on these data in a DB transaction, using locks. So:
User tries the coupon, you get the ID
Start a DB transaction, get the coupon row from it, and lock it
Do what you need to, then invalidate the coupon
End the DB transaction, release the lock
The database do not necessarly need to be a standalone RDMS, in a simple case, even SQLite is sufficient. Anyway, DBs most certainly handle race conditions betten than you (or most of us) can.
If you prefer avoid database transactions you can use a Set with all the generated coupons and a set referencing only available coupons. When a user select a coupon in a synch block remove the coupon from available ones. The second user then fail to obtain it
In my application, whenever a user performs any activity I need to send an update to his followers. This requires retrieving the followers list, at first, from the DB.
So for each update operation I need to retrieve the list & then write to those from list of followers.
Since there may be multiple times that the app may need to write an update for a user's followers while user in session, thus I'm wandering what if I can batch those write operations. So,
Should database write operations be batched by first storing the user's activity data in JSF session map? and then performing batch write operations at the end of session (or after certain timed interval or some threshold no. of updates) !?
Perhaps a way to implement this could be, using the #PreDestroy method of a #SessionScoped bean !? Before destroying I would ask to play all the write operations, that are in stock, to the DB. This way I could save lot of reads and batch multiple writes related to same tables.
(User Experience wise, there is no issue if they get the update this much late.)