i need some suggestions in designing application, in my application there will be insurance cases and according to roles users will access the cases and different level of life cycle of the Case.Here i need to restrict users to access same case.If one user is accessing one case with caseid (123) and other user should not able to access same case(123). Please can anyone suggest how can i achieve this.
You need some kind of locking. Depending on your specific requirements there are different ways to accomplish this.
For web applications you can use this algorithm which uses a table to store locks and ajax to refresh the locks as long as the user remains on the edit page. The algorithm can be used even if you don't use PHP on the client.
Following is one way of doing this
Make provision in the database (add a column) to indicate that, that particular case is being accessed.
When a user access a case, check the database field if that case is already being accessed, if not update the database field indicating the same.
If another user, tries to access the same case, then based on the database field value appropriate response will be send
Its important to note that the transactions mentioned in #2 i.e. database read and update should be ATOMIC.
The way you are planning to implement locking is not a good practice. I am not sure about my sql but if you are using microsoft sql or oracle then the best practice is to implement optimistic lock mechanism.
The link given below should help you understand better.
www.asp.net/mvc/overview/getting-started/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application
Related
Without relying on the database, is there a way to ensure a field (let's say a User's emailAddress) is unique.
Some common failure attempts:
Check first if emailAddress exists (by querying the DB) and if not then create the user. Now obviously in the window of check-then-act some other thread can create a user with same email. Hence this solution is no good.
Apply a language-level lock on the method responsible for creating the user. This solution fails as we need redundancy of the service for performance reasons and lock is on a single JVM.
Use an Event store (like an Akka actor's mailbox), event being an AddUser message, but since the actor behavior is asynchronous, the requestor(sender) can't be notified that user creation with unique email was successful. Moreover, how do 2 requests (with same email) know they contain a unique email? This may get complicated.
Database, being a single source of data that every thread and every service instance will write to, makes sense to implement the unique constraint here. But this holds true for Relational databases.
Then what about NoSql databases? some do allow for a unique constraint, but it's not their native behavior, or maybe it is.
But the question of not using the database to implement uniqueness of a field, what could be the options?
I think your question is more generic - "how do I ensure a database write action succeeded, and how do I handle cases where it didn't?". Uniqueness is just one failure mode - you may be attempting to insert a value that's too big, or of the wrong data type, or that doesn't match a foreign key constraint.
Relational databases solve this through being ACID-compliant, and throwing errors for the client to deal with when a transaction fails.
You want (some of) the benefits of ACID without the relational database. That's a fairly big topic of conversation. The obvious way to solve this is to introduce the concept of "transaction" in your application layer. For instance, in your case, you might send a "create account(emailAddress, name, ...)" message, and have the application listen for either an "accountCreated" or "accountCreationFailed" response. The recipient of that message is responsible for writing to the database; you have a couple of options. One is to lock that thread (so only one process can write to the database at any time); that's not super scalable. The other mechanism I've used is introducing status flags - you write the account data to the database with a "draft" flag, then check for your constraints (including uniqueness), and set the "draft" flag to "validated" if the constraints are met (i.e. there is no other record with the same email address), and "failed" if they are not.
to check for uniquness you need to store the "state" of the program. for safety you need to be able to apply changes to the state transactionally.
you can use database transactions. a few of the NoSQL databases support transactions too, for example, redis and MongoDB. you have to check for each vendor separately to see how they support transactions. in this setup, each client will connect to the database and it will handle all of the details for you. also depending on your use case you should be careful about the isolation level configuration.
if durability is not a concern then you can use in memory databases that support transactions.
which state store you choose, it should support transactions. there are several ways to implement transactions and achieve consistency. many relational databases like PostgresSQL achieve this by implementing the MVCC algorithm. in a distributed environment you have to look for distributed transactions such as 2PC, Paxos, etc.
normally everybody relies on availabe datastore solutions unless there is a weird or specific requirement for the project.
final note, the communication pattern is not related to the underlying problem here. for example, in the Actor case you mentioned, at the end of the day, each actor has to query the state to find if a email exists or not. if your state store supports Serializability then there is no problem and conflicts will not happen (communicating the error to the client is another issue). suppose that you are using PostgreSQL. when a insert/update query is issued, it is wrapped around a transaction and the underlying MVCC algorithm will take care of everything. in an advanced and distrbiuted environment you can use data stores that support distributed transactions, like CockroachDB.
if you want to dive deep you can research these keywords: ACID, isolation levels, atomicity, serializability, CAP theorem, 2PC, MVCC, distributed transacitons, distributed locks, ...
NoSQL databases provide different, weaker, guarantees than relational databases. Generally, the tradeoff is you give up ACID guarantees in exchange for increased scalability in the dimensions that matter for your application.
It's possible to provide some kind of uniqueness guarantee, but subject to certain tradeoffs. With NoSQL, there are always tradeoffs.
If your NoSQL store supports optimistic concurrency control, maybe this approach will work:
Store a separate document that contains the set of all emailAddress values, across all documents in your NoSQL table. This is one instance of this document at a given time.
Each time you want to save a document containing emailAddress, first confirm email address uniqueness:
Perform the following actions, protected by optimistic locking. You can on the backend if this due to a concurrent update:
Read this "all emails" document.
Confirm the email isn't present.
If not present, add the email address to the "all emails document"
Save it.
You've now traded one problem ... the lack of unique constraints, for another ... the inability to synchronise updates across your original document and this new "all emails" document. This may or may not be acceptable, it depends on the guarantees that your application needs to provide.
e.g. Maybe you can accept that an email may be added to "all emails", that saving the related document to your other "table" subsequently fails, and that that email address is now not able to be used. You could clean this up with a batch job somehow. Not sure.
The index of emails could be stored in some other service (e.g. a persistent cache). The same problem exists, you need to keep the index and your document store in sync somehow.
There's no easy solution. For a detailed overview of the relevant concepts, I'd recommend Designing Data-Intensive Applications by Martin Kleppmann.
What is the best strategy when building a user creation module which is deployed in multiple clusters?
Basically, want to avoid different user from being picking same username, username is unique ID, as same username request can be triggered to different cluster at same time.
Each creation will search for the existence of requested username.
Thanks in advance
For unique user id you can use UUID class and its method randomUUID(). This class is the answer for this specific need. As for user name One of the solutions would be to have a single DB or DB table for all clusters, so the check would be done against the same source by all clusters and synchronization issues could be dealt with on transaction level, and you can define username column as Unique. Another idea is that you have a webservice that is hosted on a single server possibly outside of your cluster. This service will be responsible for verifying and writing User names and all your clusters will use this service. It will be this service responsibility to deal with concurrency issues. The most primitive solution of course to make it sequential i.e. one request at the time. Sometimes it could be good enough. If not there are other techniques with better performance but more complex
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.
I have a login page which connects to a Database, the Database has only one client, when a user logs on he/she may make certain changes to his profile and then save. A large number of frames require the current user id in order to manipulate his data
Among the possible ways of storing the user currently logged in is
1) to save the data to a temporary text file and persist it before the user logs out
2) another option would be to use variables across all the frames ,however I'm not too confident about this
3) a third way would be to have a Boolean column in the database and to persist the the data of the field with true in it
Perhaps there are better ways of storing the current user Id could somebody elucidate other possible methods and highlight the pros and cons of each implementation with reference to an "optimal" method of doing this
Edit: This is a desktop application
I would suggest not to share this information in any static context for the reason it will render your project as very hard to test once it gets big enough. See this link for more info: When to use singletons, or What is so bad about singletons?
What I would do is store session objects in some map, identifying the appropriate session by an ID that will be given and sent back to you via client cookie. This is how the web has been doing it for years, and it is still doing it this way. Simply pass the session object around to any class that requires access to that data when it needs it.
If you are using a J2EE implementation, then you may already have support for sessions within that implementation, you should check out "How to Use Sessions"
This is more of a software design question, and covering the basis to complete the patterns used to support what I just suggested is unfortunately beyond the scope of the question
The logged user is an instance of the class Person or LoggedUser.
You have to instantiate it and share its reference between Views via a Model.
I'm multing a multi-tenant SaaS web-application in Java, Spring, Struts2 and Hibernate. After a bit of research, i choose to implement multi-tenancy in a shared db, shared schema, shared table approach. And tagging each db-line with a tenantId.
I have rewritting my application, so Managers and Dao's will take the tenantId as a parameter to only serve the correct db-resources.
This works perfect for all view's when getting information. And also for creating new stuff (using the logged in users tenantId to store the info).
However, for updating and deleting stuff I am not sure how to secure my application.
For example: When a user want to edit an object, the url will be: /edit?objectId=x
And this is mapped to an action that will retrieve this object by Id. Meaning any logged in user can by url-modification view any object.
This i can solve by adding the tenantId to the Dao so if the User tries to view an object outside his tenancy he will get nothing.
Ok thats ok then, but about when sending in the edit-form?
What if the user modifies the request, messing with the hidden field objectId so the action will receive a request to alter an object not belonging to the users tenancy.
Or if the users url-modifies a delete action /delete?objectId=x
Basicly I need some way of assure that the logged in user has access to whatever he is trying to do. For all get's its easy. Just putting the tenantId in the where clause.
But for updates and deletes i'm not sure what direction to go.
I could query the db for every update and delete to see if the users has access to the object, but i'm trying to keep db-interaction to the minimum. So i find it impractical to make an extra db-call for every such action.
Does anyone have any hints or tips to my issues?
The same for reading applies to writing/updating: user can only see/access/change what they own. Your question is more about database that about anything else. The same constraints you apply to viewing data must also apply to writing data.
In this case, you don't want to wear the performance of a query first then an update. That's fine, since you can update the database with conditions. Since this seems likely to be database-level in your case you need to know what your database is capable of (to do it in one go). For example, oracle has the merge statement.
I am quite late to this thread and maybe you have already built the solution you were asking here about. Anyway, I have implemented a database-per-tenant multitenant web application using Spring Boot 2 and secured the web access using Spring Security 5. The data access is via Spring JPA (with Hibernate 5 as the JPA provider). Do take a look here.