Best way to handle concurrency issues

后端 未结 11 1203
迷失自我
迷失自我 2021-02-07 23:27

i have a LAPP (linux, apache, postgresql and php) environment, but the question is pretty the same both on Postgres or Mysql.

I have an cms app i developed, that handle

相关标签:
11条回答
  • 2021-02-07 23:41

    I suggest: when you first query the record that might be changed, hang onto a local copy. When "updating", compare the copy in the locked table/row against your copy, and if it's changed, kick it back to the user.

    0 讨论(0)
  • 2021-02-07 23:43

    I agree that I probably wouldn't hit the database for this. I suppose I would use APC cache (or some other in-memory cache) to maintain this information. What you are describing is clearly optimistic locking at the detailed record level. The higher the level in the database structure the less you need to deal with. It sounds like you want to check with multiple tables within a structure.

    I would maintain a cache (in APC) of the IDs and the timestamps of the last updated time keyed by the table name. So for example I might have an array of table names where each entry is keyed by ID and the actual value is the last updated timestamp. There are probably many ways to set this up with arrays or other structures but you get the idea. I would probably add a timeout to the cache so that entries in the cache are removed after a certain period of time - i.e., I wouldn't want the cache to grow and assume that 1 day old entries aren't useful anymore).

    With this architecture you would need to do the following (in addition to setting up APC):

    • on any update to any (applicable) table, update the APC cache entry with the new timestamp.

    • within ajax just go as far "back" as php (to obtain the APC cache to check the entry) rather than all of the way "back" to the database.

    0 讨论(0)
  • 2021-02-07 23:44

    Polling is rarely a nice solution.
    You could do the timstamp check only when the user (with the open document) is doing something active with the document like scrolling, moving the mouse over it or starts to edit. Then the user gets an alert if the document has been changed.

    .....
    I know it was not what you asked for but ... why not a edit-singleton?
    The singleton could be a userID column in the document-table.
    If a user wants to edit the document, the document is locked for edit by other users.

    Or have edit-singletons on the individual fields/groups of information.

    Only one user can edit the document at a time. If another user has the document open and want to edit a single timestamp check reveal that the document has been altered and is reloaded.

    With a singleton there is no polling and only one timestamp check when the user "touches" and/or wants to edit the document.

    But perhaps a singleton mechanism doesn't fit your system.

    Regards
       Sigersted

    0 讨论(0)
  • 2021-02-07 23:49

    You will need some type of version stamp field for each record. What it is doesn't matter as long as you can guarantee that making any change to a record will result in that version stamp being different. Best practice is to then check and make sure the loaded record's version stamp is the same as the version stamp in the DB when the user clicks save, and if it's different handle it.

    How you handle it is up to you. At the very least you'd want to offer to reload from the DB so the user can verify that they still want to save. One up from that would be to attempt to merge their changes into the new DB record and then ask them to verify that the merge worked correctly.

    If you want to periodically poll any DB capable of handling your system should be able to take the poll load. 10 users polling once every 5 seconds is 2 transactions per second. This is a trivial load, and should be no problem at all. To keep the average load close to the actual load, just jitter the polling time slightly (instead of doing it exactly every 5 seconds, do it every 4-6 seconds, for example).

    0 讨论(0)
  • 2021-02-07 23:51

    I think you can use a condition in the UPDATE statement like WHERE ID=? AND LAST_UPDATE=?.

    The idea is that you will only succeed in updating when you are the last one reading that row. If someone else has committed something, you will fail, and once you know you've failed, you can query the changes.

    0 讨论(0)
提交回复
热议问题