i have a question that i couldn't find a satisfying answer.
i have a "Add Product" screen, this product has zero or many images. In this same screen there is the upload option.
My question is: how can i upload pictures to the product, if i don't have it`s id yet? since it is not saved on database yet.
Is there any best practice for this situation?
Thanks in advance
I'm just listing down my points on how to handle it:
Handle both at once - Send the Picture and Details of the product at once on save/add button click using enctype=”multipart/form-data” (Using spring)
Now you can handle in your code. Perform validations.
If it passes all validations, then upload the image/save the image.
Send the url/filepath to the Object/DB where product is getting saved.
Drawback:
Say user has already uploaded the files and is filling the product details. In which case, We're still waiting for user to enter all the details of the Product and then upload.
The final upload during save is going to take time. (Second option can overcome this)
Upload Images First as in when they're available and then Product on save -
Upload the Image first to the server (As in when user adds an image, keep uploading).
Let Server save all these images at a temp-place and return a UUID number to uniquely identify these images.
On save/add action, let client send all those UUID's list that it got from server during upload time. Now server can identify what all images can be moved from temp directory back to central server or associate the images with Product.
You can have another Cron Job or SessionTimeoutListener or A call from client when user backs out of Product Page without save or A combination of all 3 to remove those images which are not associated with any product for say last X minutes (Session timeout minutes)
Drawback:
Needs a lot of changes and post-processing/clean-up overhead.
Handle Product first then Image -
Push product details first to server on save and server return the productId that got saved.
Now client makes another call to server with productId and Images.
Drawback :
We're relying on client to handle transactions, which is bad.
Inconsistency with data might grow.
The time taken for the entire process might grow compared to other 2 approaches.
PS : I feel the second opinion to be good. This is just my opinion.
Related
I have generic problem where I am loading data from backend in blocks i.e. in pages.I have created cache which stores maximum 2-3 pages at a time.
Say page 1 - 1-1000
Page 1001-2000
class page{
List<Data>, startoffset, endoffset, pageno}
Here client could be UI or any other service.
Now client is asking for data from 1-100,101-200. Till the time the range is being served from one page, I can accommodate the changes by calculating page no from supplied range.
If page no is not there, I can load that range from backend and keep it in cache.
However, I am facing issue when client request for data that overlaps over multiple blocks.
example- when client asks for Page 950-1050, then data is spanning over two pages.
Any suggestion on how to model classes/blocks in such case i.e. how to keep server side data in memory in blocks and send it to GUI.
I don't see a problem in using two (or even more) contiguous blocks fetched from DB enough to cover the region requested for ui. You can do it both eagerly and lazyly ( that is discover that you don't have enough rows and fetch extra). This is pretty normal situation for the kind of process you try to execute. Overlapping is present always in cases when user is free to choose desired region
I'm currently developing an application in Java that connects to a MySQL database using JDBC, and displays records in jTable. The application is going to be run by more than one user at a time and I'm trying to implement a way to see if the table has been modified. EG if user one modifies a column such as stock level, and then user two tries to access the same record tries to change it based on level before user one interacts.
At the moment I'm storing the checksum of the table that's being displayed as a variable and when a user tries to modify a record it will do a check whether the stored checksum is the same as the one generated before the edit.
As I'm new to this I'm not sure if this a correct way to do it or not; as I have no experience in this matter.
Calculating the checksum of an entire table seems like a very heavy-handed solution and definitely something that wouldn't scale in the long term. There are multiple ways of handling this but the core theme is to do as little work as possible to ensure that you can scale as the number of users increase. Imagine implementing the checksum based solution on table with million rows continuously updated by hundreds of users!
One of the solutions (which requires minimal re-work) would be to "check" the stock name against which the value is updated. In the background, you'll fire across a query to the table to see if the data for "that particular stock" has been updated after the table was populated. If yes, you can warn the user or mark the updated cell as dirty to indicate that that value has changed. The problem here is that the query won't be fired off till the user tries to save the updated value. Or you could poll the database to avoid that but again hardly an efficient solution.
As a more robust solution, I would recommend using a database which implements native "push notifications" to all the connected clients. Redis is a NoSQL database which comes to mind for this.
Another tried and tested technique would be to forgo direct database connection and use a middleware layer like a messaging queue (e.g. RabbitMQ). Message queues enable design of systems which communicate using message. So for e.g. every update the stock value in the JTable would be sent across as a message to an "update database queue". Once the update is done, a message would be sent across to a "update notification queue" to which all clients would be connected. This will enable all of them to know that the value of a given stock has been updated and act accordingly. The advantage to this solution is that you get to keep your existing stack (Java, MySQL) and can implement notifications without polling the DB and killing it.
Checksum is a way to see if data has changed.
Anyway I would suggest you store a column "last_update_date", this column is supposed to be always updated at every update of the record.
So you juste have to store this date (precision date time) and do the check with that.
You can also add a column version number : a simple counter incremented by 1 at each update.
Note:
You can add a trigger on update for updating last_update_date, it should be 100% reliable, maybe you don't need a trigger if you control all updates.
When using in network communication:
A checksum is a count of the number of bits in a transmission unit
that is included with the unit so that the receiver can check to see
whether the same number of bits arrived. If the counts match, it's
assumed that the complete transmission was received.
So it can be translated to check 2 objects are different, your approach is correct.
When I make an app, I always wonder when is the best moment to load data from a remote database.
If the app ask for a login screen, then:
Is it better to launch every data from remote DB at his time, and then use them in the app? This way, the app is much faster after the login screen (no more queries needed to retrive some data)
Is it better to load data only when we need to use them (for example, display some data from DB into the app). This way, the login is much faster, but the app can be slower than the first case.
What do you guys think?
It depends on the scenario, but I would go with option 2: First, the user is granted the access and you retrieve the data from your backend when needed.
Imagine a very simple scenario where the user logs in to see a list of products he can work with (add and remove). The solution would consist of 2 screens:
A login screen to manage user access
product list screen to work with products
For me, in a good design each screen has its own resposibility, and each screen should query only the data that it is going to manage.
The login screen responsibility would be only to perform the login and then navigate to the product screen.
The product screen responsibility would be retrieve the products, show them and store them when the user has ended the editings.
If your login screen queries the product data to pass it to the product screen, you are coupling the login screen and the product data.
Anyway, if you have a set of static data that can be used by several screens (for example product categories), you can query them the first time you need them and store them in a cache for further accesses.
Another scenario could be if there can be conectivity problems. In this case the best solution could be to download a set of data that the user can work with, edit them and them upload them to the backend (taking into account the possible concurrency issues).
If you want to logIn your user you have to call the remote DB to authenticate the user. I do not see where you are able to do this without the remote db.
Otherwise you are correct that you should only query the DB if you want to show the data you get.
I have to solve this situation: in my Spring + JPA web application I have a jsp similar to an excel work sheet.
So I have a certain number of cells and each cell is saved in a DB table with additional information: I have a row for each cell.
id | value | column | row | ...
I use this structure because number of columns in my jsp table is dynamic.
At the moment, when I save cells I truncate the current set of rows in DB table and re-insert all the new rows. This is the fastest way I found to update a large set of rows.
But now I have a concurrency problem: the jsp page can be used by different users at the same time and this can cause overwriting problems on other users savings.
I need to implement some kind of lock in my web app. I found there are mainly two types of lock: optimistic vs pessimistic.
Can you suggest me a common approach to solve this situation? Where do I need to implement the lock, at data access level or at service level?
NOTE to be more clear: table values are shared among users, but can be updated by anyone among authorized users.
The solution would probably depend on the behavior requirements.
How about the following scenario: users A and B started to change some values, then user A pressed Save button and saved data, after that user B did the same. User B got an error message saying something like "the data has been updated, please reload the page". He reloads the page and lose all changes he did :( Only after that he is able to save his changes, but he has to do it once again.
Other possible scenario: users A and B accessing the page, but only the user who was the first will be able to save his work, other users will see message saying something like "someone else is editing the page, try again later".
For the first scenario you can implement the following: each line of the table (in database) has a last-update-timestamp which is updated to current time each time this row is changed.
Now, let's imagine user A get row with timestamp 1 when opened the page, user B was a little bit slower and got the same row with timestamp 2. But, he did his changes faster and pressed Save button first. Now, the row is saved in DB with timestamp let's say 5. User A is trying to save his changes, but the timestamp of his data is 1, which is different from 5 currently in DB. That means someone changed that data already and he should see error message I mentioned above.
Second scenario is a little bit harder to implement. I think the best way to do this is to open transaction to DB which
reads the row(s) we want;
put some flag like "locked" to true for all of them;
if some row is locked already, fails (or return available rows, depending on what you need). But, probably should fail;
returns rows to jsp page;
Now, if other user requested the same rows, transaction will fail and he will not be able to start changing data.
User A should put these locked flags back to false when he saves the data.
Important thing: these locks should have timeout to prevent situation when user opened the page and closed it without saving (or browser crash, or something else). You may also want to implement some kind of lock reackquire for the same user - when user opened the page for the first time, then closed it without saving data and opened once again - he should be able to edit the data. This can be done by identifying user somehow - login, cookie, and so on.
I have ran into a small issue with an Android App that I am currently working on.
I have a list of points of interest declared in an XML file. The POI's look like this:
<hotel>
<name>Hotel Atlas</name>
<latitude>45.612079</latitude>
<longitude>25.660756</longitude>
<thumb_url>/hotels/atlas.jpg</thumb_url>
<phone>039999999</phone>
</hotel>
The problem that I have is that there are about 200 points of interest and every time the users access the app the XML is read every time from an online location and that means high volumes of internet traffic. The XML is stored online so I can update it every time I want to add another POI and not force users to update the app. Is there any way to send this data to the app and not require to download the entire XML?
I have not yet found an optimum sollution for this and decided to ask for some opinions.
Thanks, Vlad
There are only 2 possible ways:
Either give static database with all POI or
Load data from web whenever required.
Now you can do one thing, keep static database with App. Make web call once app starts and check for the updated data if any changes you made in server database. If there is any change on server database, then update only those data to the local(static) database.
For implementing above step, you must have to pass Last Updated date to/from server. I mean whenever you make web call, you need to pass last updated date from the client, server will check for new data to be updated post this date. Server will store client date as updated date and return back to client.
Maybe it's possible to store POIs like "One POI - One file"? In this case you can easily read only new points from server