I think my current problem is describable very quick.
I have a symfony2 project with doctrine accessing the mysql database.
Now multiple (many) users can visit this page at the same time.
Now, my problem is the following:
Users can click a button to mark himself as a participant of an entry.
An entry can have a maximum of allowed participants.
E.g.:
ENTRY A, max. users = 3 <----- USER A, B, C and D viewing ENTRY A.
Now, A marks himself as an participant by clicking an Ajax Button.
B do the same (not at the same time -> no problem).
Now C and D fight for the last free slot in ENTRY A.
Both click on the button at the same time.
It can happen now that C and D both can join this entry, even if the max. users of 3 is exeeded.
If an user clicks on the Ajax Button, an ajax call gets send.
On the server side, in the ajax handler, my symfony2 code will use doctrine to access the db.
It simply requests the entry from database and checks if the maximum of users already reached.
If not, the user gets saved/marked as an participant of the entry.
But that's not allowed. I want to avoid that 2 users can click on the button at the same time to join the entry.
In this state, max. users in the entry is defined to 3 and the amount of participants for this entry is 4. That's not the goal of this function.
Can you explain me how to fix this?
Do i need table locking or something else?
If it is not exactly clear what the problem is, then just ask.
I look forward to answers and i am grateful for each hint.
Best
titan
Seeing as you're using MySQL you could use
http://dev.mysql.com/doc/refman/5.0/en/miscellaneous-functions.html#function_get-lock
http://dev.mysql.com/doc/refman/5.0/en/miscellaneous-functions.html#function_release-lock
How you code it is up to you, but it can be used to mitigate concurrency issues like the one you have.
Have a look at Transaction and concurency on doctrine doc http://doctrine-orm.readthedocs.org/en/latest/reference/transactions-and-concurrency.html
Related
I've built a page with POST method form.
The form has a list of orders and tracking number for each order.
On this page two people are working at the same time, updating tracking numbers for order.
Example: when person 1 is updating the form with tracking number for order #126792 and click Submit, the database will be update tracking number for order #126792 and leave empty field for order #127299
At the same time person 2 is updating tracking number for order #127299, the database will update tracking number for order #127299 BUT insert empty tracking number for order #126792
You can see the form below in attached image, how can this situation be solved ?
Thank you.
Your question is too broad since it really depends on how your system and your users behave. Also, without you providing any code, I can't really answer with code.
However, I can provide a kind of decision alghorithm that might help you...
Questions:
Can the same record be updated by 2 different users at the same time?
No: Proceed to 2
Yes: Solution C, D or E
Can a user update 2 orders at the same time?
No: Solution A
Yes: Proceed to 3
Are empty values meaningful? (that is, can a user update/delete a record by submitting an empty "tracking code"?)
No: Solution B
Yes: Solution C, D or E
Solutions:
A. Change the frontend so that the user can only update 1 order BOX at a time
B. Ignore empty/false/null values in the backend.
C. Lock the records being edited:
User selects the records to update and informs the backend
The backend locks the records being updated until the user updates it or the "update time" expires
D. Use a version system: make each update a new version of the records and if a conflict arises, ask the last user that tried to update to resolve before committing the data.
E. Make the records "real time" (with short polling or long polling)
NOTE: Keep in mind that this assumes users are "smart", that is, they only behave in a predictable way (that you can specify without code) and they will oblige and won't try funny stuff.
I have a script that is written in PHP. It uses MySQL database to store records.
Basically, I have team of users that are making random calls to a different business. I want to add list of phone number in a queue "pool table". The system will need to assign the new call to the user. Now If a user is already working on a phone call I don't want another user to start calling the same number. I need a solution to prevent 2 people having the same record assigned to them. So if phone number 000-000-0000 is assigned to the user X the same record will be skipped and the next one in line get assigned to the next available user.
This table will be accessed a lot so I need a good solution that will prevent 2 people from working on the same record and also not cause system issues.
One way I can think of but looking for a better solution is
open transaction
select a call where record status is available
update that call by changing the status from records available to record pending.
commit transaction.
If the use completed the call then updated with a status of completed otherwise make the record available again.
what are other solution available for me?
Thanks
Without a little more information about the workflow, it's hard to know what to suggest, but it sounds like users are interacting with the application somehow while they are taking calls...true??
If so, you must have some way for the user to alert the system they are ready for a call.
ie...
I just started my shift... Deal me a number.
Or...
Submit notes from last call... click submit and Deal me another number.
In this scenario, it seems like it should pretty easy to just let the users "request" the next number. You could probably just insert the users id on that record so it shows in their queue.
I have setup a referral system, whereby a user enters their email address and can then refer a friend. The friend is given a unique url followed by a code, ie: example.com/FHF73H
The DB is setup as such;
email_id email code ts
1 test1#test.com 98VIB15 2011-03-17 01:52:22
2 test2#test.com 412395D 2011-03-17 01:58:00
3 test3#test.com 6521298 2011-03-17 02:00:51
4 test4#test.com 3VJ7AB5 2011-03-17 02:01:02
I have htaccess setup so RewriteRule ^([a-z0-9]+)$ /index.php?_url=$1 [NC,L,QSA] and I can then use $_GET['_url']; to get the referrer code.
For each user in the DB, I want to track:
a) A count of how many people have visited their referral link
b) A count of how many users have then gone on and subscribed (by entering their email address and submitting)
c) A comma-seperated column of the email_id's of the users who performed b).
Essentially 3 columns are required.
Where must each of the above (a, b, and c) be placed in the code to function the way I'd like? I'm also unsure how to code all that up in PHP and what certain-type of column properties are required in the MySQL database.
Any help would be very much appreciated!
Thank you!
A)
There are 3 ways you can count how many times a referral link has been clicked.
Every click made, always
Everytime the URL is called, you update the value in your database. This means one person can continually click and it will all be stored. Intentionally or not.
Every independent click
You'll store a cookie on the user, and only increase the count when this cookie is not present. This will prevent people from accidentally increasing the count if they click the link two times. However, they are still able to clear their cookies to increase count.
Every unique click
Here you choose to store what IP the click came from, and only increase count when the IP is not already present in the database.
B)
You'll have to save a cookie (regardless of above method). In this cookie you'll save whatever ID this referral had in your database.
In extreme cases, you might want to save to a database instead of a cookie to prevent people from clearing their cookies as to fake not being referred by anyone or the user doesn't accept cookies at all.
There is, of course, the possiblity to not save anything at all, and have the user land directly on the registration page. But the referrers ID will be lost if the users leaves or changes page.
C)
I wouldn't use CSV on a RDBMS in this case, instead I would probably have a new table with user_id (the person who registered) and a referral_id (ID of the referral). CSV or serialized data can be needed sometimess, though.
Summary
The user clicks on a referral link, you save a cookie of the ID of the referral on the users browser and increase the click count of this ID in your database.
When the user submits the registration form, you check for a cookie, if the cookie is found, you increase the referral count based on what referral ID was inside this cookie,
I have a bunch of pages on a site for which the actions that can be taken on one page are contingent upon the info in the database for the site visitor. So, let's say Visitor A comes to page B and updates a database to show that they have joined a certain group. Then the visitor goes to page C, the group page. If the user is a group member, they are shown member content. If they are not, they are shown non-member content. Here comes the issue (btw, pages are in php):
In an ideal world, the query run on page B would be completed instantaneously before the user goes to page C so the database is always filled with the most recent info on membership states. However, it can happen that the server is under a lot of load and the query does not complete by the time the user goes to page C. So, even though the user is a member of the group, that is not reflected on page C since the query has yet to complete.
Is there a way to make it so that if a user run a query on a page, until that query completes any other page they try to visit will just "hang" and load after there query is complete, or until a given amount of time has passed? I can make this system manually, but if mysql and php already have something built in, that would be preferable.
In case it matters, I am using a LAMP server.
Unless you do anything fancy like replicated database servers or message que systems, this is in fact how a single MySQL server and PHP already work. Issue the UPDATE or INSERT on page B, and the query wont return until it is committed. So don't return any HTML from page B until you have done the query - which you won't want to anyway, as you will want to make sure there was no error first. Then page C will be fine.
Can't the visitor simply be not shown the link to page C until the confirmation happens in page B? So they join the group in page B which happens by submitting a form post to a separate intermediate form processor page F, and then once that's done (ie mysql insert completed successfully), it loads page B again with the proper new information and directions to page C.
If page C links have to appear always, or the user can have it bookmarked, then perhaps page C can also display the date of the record, offering the user a "Refresh" button in case his record doesn't match what he just did as a way of telling him to wait a bit and try again.
In any case, in mysql you're talking about the concept or row locking but you're trying to apply that to a multi-entry site. I don't know of any such built-in mechanism in PHP but you could fake it with semaphores per user if you'd like:
user initiates action
PHP sets a lock for that user either by creating a unique file, or setting a unique key in a memory store like memcache, or in the user session
that lock indicates that the action has not finished yet
PHP performs action (mysql insert, whatever)
once action is complete and validated, remove lock
Then you can use the existence of the lock to determine wether page C should load and display something descriptive to the user, such as my above suggestion of a Refresh button.
Assuming you have a string that uniquely identifies the current user, say 'identifyuser', pick a reasonable timeout and do a SELECT GET_LOCK('identifyuser',timeout) before any other database activity for a given request and SELECT RELEASE_LOCK('identifyuser') after all database activity for the request.
I'm doing a system with Codeigniter , this is my first system with CI, and i'm also novice to PHP too.
I'm doing this for a hospital, in this i have the following problem
junior doctor first check the 1st visit patients and then if he can't handle them he refer them to the senior doctor
from registration room some patients are send to the eye checking room to check their eyes and then they go to the junior doctor
like wise i have temporary data to be kept on the system, references from one room to another and so on...
i need to get this details to the main GUI of the each person; for example in the Senior doctors UI there will be a tab named 1St time patients, in that the patients that was referred by the junior doctor will be shown to him! so i need to refer to the patients that was sent to senior doctor from the junior doctor and show them in the senior doctor's UI.
so my problem is how can i keep this temporary data to be referenced by the system? keeping them in the tables is not appropriate as i think because at the end of the day these data is not stored any where, only the patient table and few other tables will be keeping the data.
guys how can i achieve this kind of thing? any method of achieving this? technology that is easier to master that will allow me to keep temporary data?please give me some references or help by code to over come this problem.
regards,
Rangana
If the data is truly temporary, and has to be used by only one user at a time you need to stick it in session.
An entry level tuorial is here:
http://www.w3schools.com/PHP/php_sessions.asp
However if data is accessed by different users, but is simply not needed on following days, or you are storing a significant amount of data, you should probably keep it in the DB.
The DB should be able to store lots of data, so on a smallish app there is not much reason to keep clearing it out, but you could also include a housekeeping function that clears data that is old or irrelevant.
However when working with medical data, it may be a good idea to hang on to everything.
everything will do with ajax (or something that always refresh the browser for number of time like meta refresh tag) that will notify senior / junior doctor if any patient referred to them.
you need to add a flag at database if the doctor already retrieve the notification so it will not notify the doctor twice.
for example your database table :
Name of patient | referral | referrer | flag_retrieved
you need to specify referral doctor at the session so it can retrieve the correct record and then notify the doctor
then your system should :
request to database if any doctor to
refer patient to them over time (you can use ajax or meta tag)
database will check if any record match and not yet retrieved
send request to browser, than notify the doctor if any referred patient.
if you need to clean up the database, you can use cron every end of day for deleting any record at the table.