Revision 32a0b855

b/snf-cyclades-app/synnefo/api/servers.py
393 393
        transaction.commit()
394 394

  
395 395
    try:
396
        vm = VirtualMachine.objects.select_for_update().get(id=vm.id)
396 397
        jobID = create_instance(vm, nic, flavor, image)
397 398
        # At this point the job is enqueued in the Ganeti backend
398 399
        vm.backendjobid = jobID
b/snf-cyclades-app/synnefo/logic/backend.py
74 74
    vm.backendopcode = opcode
75 75
    vm.backendlogmsg = logmsg
76 76

  
77
    # Update backendtime only for jobs that have been successfully completed,
78
    # since only these jobs update the state of the VM. Else a "race condition"
79
    # may occur when a successful job (e.g. OP_INSTANCE_REMOVE) completes
80
    # before an error job and messages arrive in reversed order.
81
    if status == 'success':
82
        vm.backendtime = etime
83

  
77 84
    # Notifications of success change the operating state
78 85
    state_for_success = VirtualMachine.OPER_STATE_FROM_OPCODE.get(opcode, None)
79 86
    if status == 'success' and state_for_success is not None:
......
100 107
            # Issue and accept commission to Quotaholder
101 108
            if not already_deleted:
102 109
                quotas.issue_and_accept_commission(vm, delete=True)
103

  
104
    # Update backendtime only for jobs that have been successfully completed,
105
    # since only these jobs update the state of the VM. Else a "race condition"
106
    # may occur when a successful job (e.g. OP_INSTANCE_REMOVE) completes
107
    # before an error job and messages arrive in reversed order.
108
    if status == 'success':
109
        vm.backendtime = etime
110
                # the above has already saved the object and committed;
111
                # a second save would override others' changes, since the
112
                # object is now unlocked
113
                return
110 114

  
111 115
    vm.save()
112 116

  
......
296 300
        # Issue commission
297 301
        if network.userid:
298 302
            quotas.issue_and_accept_commission(network, delete=True)
303
            # the above has already saved the object and committed;
304
            # a second save would override others' changes, since the
305
            # object is now unlocked
306
            return
299 307
        elif not network.public:
300 308
            log.warning("Network %s does not have an owner!", network.id)
301 309
    network.save()

Also available in: Unified diff