Skip to content
  • David Faure's avatar
    Akonadiserver: rework handling of database deadlocks. · 5b5b9fad
    David Faure authored
    Summary:
    We can't just replay the SQL commands, that's too low-level: if we do
    INSERT, then use the resulting ID into e.g. another INSERT command, at replay
    time we might get a different ID from the first command, and then insert
    the wrong ID in the second one...
    
    So instead we want to re-run the entire handler's parseStream(), which we
    do by throwing a DbDeadlockException (from QueryBuilder), and catching that
    in the caller (Connection) using a helper class (DbDeadlockCatcher, unittested)
    which retries up to 5 times.
    
    For this to work, it means:
    - we must also rollback any chances made to in-memory caches (done by
    clearing those caches, good enough since DB deadlocks are rare)
    - ItemModifyJob which sends parts on demand, shouldn't delete after
    sending (it might be asked again) -- this was hit by GidTest (fetchAndSetGid).
    
    Still TODO:
    - delaying the updating of intervalChecker and cacheCleaner by NotificationCollector
        until commit time;
    - checking other users of QueryBuilder (who now can get a DbDeadlockException...)
    
    Test Plan:
    all this was triggered by a unittest that creates 10 sessions
    and adds 10 different attributes to the same time, one in each session. This very
    often hits the DB deadlock scenario.
    
    Reviewers: dvratil, vkrause
    
    Reviewed By: dvratil
    
    Subscribers: kde-pim
    
    Tags: #kde_pim
    
    Differential Revision: https://phabricator.kde.org/D20326
    5b5b9fad