My application working in a multi-users environment for medical records.
One of the important parts of the application is writing the medical records, doctors should always review the current written data then adding or correcting any information's as needed.
I were aware about the situation when 2 doctors (A,B) viewing the data at same time, one of them will make changes and hit save (A).
the other doctor (B) still editing the old data & he don't know about the changes applied by doctor (A).
When doctor (B) hit save, the application will compare the Version column in the database, application then return an error message ("Data has been changed by another user !!!").
My Question in this case: What choices should be available within my solution.
I'm seeking an professional solution or idea from your experiences.
My application using: Java Swing for end user client & MySQL database.
Doctor B should absolutely be notified in some way that the record has been modified since he opened it. The rest is up to you/the requirements of the program. Does it matter if Doctor A's changes are overwritten? Would it be better to have Doctor B view the changes made by Doctor A, and then decide if the changes (made by Doctor B) should still be saved? Should the changes be merged? It all depends on what you decide to design, as well as any requirements that may be imposed on the system you are creating. Without more detail on the system you are designing or its requirements, it would be impossible to provide a specific answer.
suggestion: send a real time notification
if A makes changes and hits save you could send a message "Data has been changed by another user !!!" immediately to B before B saved his changes.
This approach is similar to stackoverflow. As I write my answer, you can change your question and I will get a message
an edit has been made to this post; click to load
So if A,B,C... open data set D, they should register themselves as observers.
You can implement this approach by using websockets or polling.
Related
I have a scenario where any update/change in the data by a cms user through application/CMS needs the approval of the admin/authorizer user. There may be multiple changes in one update in a single document/record. This approval will not be done in real-time and may take few hours or may be days. Authorizer may also reject the change. So in this case what would be the best way to keep this data alive without comitting it to the database till approval or rejection. Should I create temporary or duplicate tables to keep this data temporarily in the db? But this will result in large number of temporary tables(one for each table). Or is there any other option at developer/application/java end? I am using here Oracle with Java.
You need to better understand the problem.
You do not require one datastore,
you require two datastores.
Datastore one (possible table one) will contain unapproved changes.
This is the "proposed" state.
You will write and commit all data into this datastore as soon as the user requests the change.
Datastore two (possible table two) will contain the approved changes;
this is the "real" state.
Once a change that is in datastore one has been reviewed and approved,
you must apply the change here.
A possible other solution is to use a Kafka topic:
Use a Kafka topic to store the unapproved changes.
Feed the topic to reviewers.
When approved, note the decision (in the same topic) and write the change to the database.
Note:
datastore 1 and datastore 2 can be the same table,
just have a column to indicate "approved change",
"declined change",
and "pending change".
You can always have draft and final copy of the data. Draft copy will save your work in draft mode, committed and operation like save / confirm from app can copy this into final version.
This requires one more record to identify draft / final version and you should be using draft data to show on UI.
We have a PLM system where users go and create/update objects (i.e. Products, Colorway etc...). This objects eventually gets stored to sqlserver database. The tables do have a column for modifyTimeStamp. The field has updated timestamp when a user updated an object.
We are integrating this tool with some other application. This other application needs to know when someone creates/update objects to our PLM System.
What's the best way to achieve this? Writing some kind of listener which will keep listening and if there is a change in the table, it will notify?
The other approach could be having a trigger. But, then how my code will call that trigger as the triggers are only within the scope of that table?
I think there are many ways to go about to solve this problem. I will try to describe a few.
Creating a scheduler on the listening application. I suggest to implement a scheduler that will run every given interval to fetch the latest data according to the modify time and processing them.
Creating a new API on the listening application and to call it via the creating/updating application.
Using a microservice architecture such as using messaging services between the applications to inform one or another of creation/update events.
I hope it will help you and good luck!
SQL Server has a feature called "Change Tracking". It must first be activated for a database. If it is activated, you can issue special queries that return information about data changes in a specific table.
According to the example in the docs, the query
DECLARE #last_sync_version bigint;
SET #last_sync_version = <value obtained from query>;
SELECT [Emp ID], SSN,
SYS_CHANGE_VERSION, SYS_CHANGE_OPERATION,
SYS_CHANGE_COLUMNS, SYS_CHANGE_CONTEXT
FROM CHANGETABLE (CHANGES Employees, #last_sync_version) AS C;
would return the data changes in the Employees table since #last_sync_version.
I am having this problem for the last two projects that i worked on. Both of the projects are written in Java and use Oracle 11g as DB. When i look at the code there is nothing wrong in transaction management etc. The flow is very simple and like this in code.
Connection con = null;
try {
//Get connection
//Run validation
//Insert record
//Commit
} catch() {
//Rollback
} finally {
//Close connection
}
The validation part checks for some business rules and prevents dublicate entries.
1.st case
This works fine when a user calls this part of code fully and commits the current transaction, only after that another user comes. In this case when another user wants to run this code because that the other transaction committed the changes validation part can see the record and prevents duplicate.
But when two user runs the same code at the same time sometimes duplicate records occurs. The flow is like below and i have no idea how to handle it. I've looked at isolation levels etc but none of them works for this case. The only one applicable is using unique constraint but it is not suitable for the projects.
user1 passes validation
user2 passes validation
user1 insert record
user2 insert record
2.nd case
Another case is totaly bizarre and i can't reproduce it in my tests but i witnessed it in production. When the system load is high the system creates duplicate records on a single click of a user. That means the user presses the button only one time but the system creates multiple records at the background. These records have different ids but nearly exact creation times and all the other values are the same.
We thought initially that when the system load is high the application server couldn't handle it properly (because it was an old unsopperted one) and because it happened rarely we leave it there. But after sometime later we ha to change the application server to another one for another reason and the problem persist. And the second project i mentioned has a totaly different application server.
I and two different team worked on these problems for weeks but we couldn't find a suitable solution for these two cases and we couldn't even find the reason for the second one. Any help would be welcome if you guys encountered something like this or know the solution.
You need to use Synchronization on an object to avoid duplicates. Probably the RUN VALIDATION block might be a good candidate for fixing this but it really depends on your application logic.
It has nothing to do with your Webserver you need to use an Idempotent HTTP method to submit your form.
I am just starting off with app development and am currently writing an Android application which has registered users and a list of 'challenges' which they are able to select and later mark as completed/failed.
The plan is to eventually store all users/challenge/etc data on a database though I haven't implemented this yet.
The issue I have run in to is this - in my current design each User has list variables containing their current challenges and completed challenges eg. two ArrayList fields.
Users currently select challenges from a listview of different Challenge objects, which are then added to the user's CurrentChallenges list.
What I had not accounted for is how to structure this so that when a user takes on a challenge, they have their own unique copy of that challenge that can be independently marked as completed etc, whereas at the minute every user that selects say, Challenge 1, is simply adding the same challenge with the same ID etc. as each other user that selects Challenge 1.
I supposed I could have each different challenge be its own sub-class of Challenge and assign every user which selects that challenge type a different instance of that class, however this seems like it would be a very messy/inefficient method as all the different classes would be largely the same.
Does anyone have any good ideas or design patterns for this case? Preferably a solution that will be compatible with later storing these challenges in a database and presumably using ORM.
Thanks a lot for any suggestions,
E
I'd move every aspect of a challenge that is different for each user into a new Attempt class. So Challenge might have variables for name, description etc. and Attempt would have inProgress, completed etc. Obviously these are just examples, replace them with whatever data you're actually storing.
Now in your User class, you can record challenges using a Map. Make it a Map<Challenge, Attempt> and each User will be able to store an Attempt for each Challenge to record their progress. The Challenge instances are shared between users but there is an Attempt instance for each combination of User and Challenge.
When you implement the database later, Challenge, User and Attempt would each translate to a table. Attempt would have foreign keys for both of the other tables. Unfortunately I haven't used ORMs much so I'm not sure whether they'd work with a Map correctly.
I have implement a grid which displays document metadata and the user is able to edit the document on right click. I wanted to implement a locking mechanism for this. What would be the best way to put a lock on the document when one user has opened the editor ? These documents do reside in the database.
Just add a column that specifies who currently has the file checked out. When a person tries to check out a file, if that column is set, they will not be able to check it out, and will be notified of who has it checked out. Unless you have thousands of requests per second for a single document, this method will work fine.
In addition to adding a column to say who has the file checked out and preventing access using that. You can add a timestamp for when the lock was requested.
This way, if someone requests it and the lock is, for example, 30 mins old with no changes made, they can take the lock. (If the original user didn't quit gracefully or something).
If the documents are in a database, the database itself should have support for preventing inconsistent access.
http://docs.oracle.com/javase/6/docs/api/java/sql/Connection.html#setTransactionIsolation%28int%29
If the editor does not keep database transactions/connections open for the duration of file editing, however, and the java application runs client-side rather than server-side (as you could simply create a lock in the editor for concurrency on the server side), then things get a bit trickier and I haven't yet had enough database experience to say how you would resolve that, as using a field in the database to indicate editing status would have concurrency problems with that type of setup (unless the database itself supports locking on records, but that would depend on the DB engine in use).
Oh, one possibility would be to use file modification times (have a timestamp field in the database and update it each time a file is modified) and keep a no-dirty-reads-allowed transaction in use while checking the timestamp and determining if the file was modified by another user after the user attempting to save last accessed it; if so, it won't save the file to the database and will instead alert the user that the server-side file was changed and ask if they want to view the changes (similar to how version control systems work). By disallowing dirty reads for all such transactions, that should prevent other users from changing the file's record while the first transaction is open (to mark a record as "dirty", you could perhaps use a dummy field that would be updated at the start of each transaction with some random value). (Note: aglassman's answer would work similarly to this.)