def update_qos_queue(self, context, id, qos_queue):
        qos_queue = qos_queue['qos_queue']

        with context.session.begin(subtransactions=True):
            qos_queue_db = self._get_qos_queue(context, id)
            if id == qos_queue_db.qos.default_queue_id:
                raise ext_qos.QosQueueCannotEditDefault(
                    qos_id=qos_queue_db.qos_id,
                    qos_queue_id=id)
            new_rate = qos_queue.get('rate', qos_queue_db.rate)
            rate_delta = new_rate - qos_queue_db.rate
            if rate_delta:
                if qos_queue_db.subqueues:
                    # Check new rate can afford its subqueues' need
                    self._check_qos_queue_rate(qos_queue_db, 0, new_rate)
                if qos_queue_db.parent_queue:
                    # Check parent queue can afford the delta
                    self._check_qos_queue_rate(qos_queue_db.parent_queue,
                                               rate_delta)
                else:
                    # Check parent qos can afford the delta
                    self._check_qos_rate(qos_queue_db.qos, rate_delta)

            new_ceil = qos_queue.get('ceil', qos_queue_db.ceil)
            # New ceil should not exceed its parent's ceil
            if qos_queue_db.parent_queue:
                new_ceil = min(new_ceil, qos_queue_db.parent_queue.ceil)
            else:
                new_ceil = min(new_ceil, qos_queue_db.qos.rate)
            if new_ceil < qos_queue_db.ceil:
                # Ceil changed to a smaller value
                self._set_ceil_for_queues(new_ceil, qos_queue_db.subqueues)
            qos_queue_db.update(qos_queue)
        return self._make_qos_queue_dict(qos_queue_db)