Инструменты пользователя

Инструменты сайта


eaze:samples:одновременное_редактирование_объектов

Это старая версия документа.


Отслеживание одновременного редактирования объектов в VT

По умолчанию в VT при сохранении объектов действует правило - «кто последний нажал сохранить, того и форма :)». Попробуем исправить это, поставив следующую задачу:

В VT при редактировании объекта давать сохранять именно ту версию объекта, которая была открыта на тот момент.
Если редактирование одновременно было открыто два раза, то при нажатии кнопки «сохранить» во второй раз система не должна позволить сделать это, так как в первый раз уже было произведено сохранение.

Эта схема называется "Optimistic Concurrency Control"

Реализация

Решение данной задачи можно рассматривать в различных вариантах, но мы, как программисты, определим свои ограничения заранее. У объекта могут быть связанные объекты (листы), обычно они редактируются на одной странице, поэтому нам важен сам факт нажатия кнопки «Сохранить и закрыть» или «Применить». Если в объекте ничего не поменялось, мы не учитываем это. По своей сути задача сводится к записи времени последнего редактирования объекта.

Попытаемся решить задачу в общем виде.

База данных

Создадим табличку objectHistory, в которую будут записываться все изменения.

CREATE TABLE "objectHistory"
(
	"objectHistoryId" Serial NOT NULL,
	"objectId" INTEGER NOT NULL,
	"objectType" VARCHAR(64) NOT NULL,
	"userId" INTEGER NOT NULL,
	"userType" VARCHAR(64) NOT NULL,
	"createdAt" TIMESTAMP NOT NULL DEFAULT now(),
 PRIMARY KEY ("objectHistoryId")
) WITHOUT Oids;
 
CREATE INDEX "IX_objectHistory_objectIdType" ON "objectHistory" USING btree ("objectId","objectType");
CREATE INDEX "IX_objectHistory_createdAt_desc" ON "objectHistory" USING btree ("createdAt" DESC);

Эта таблица универсальна: мы можем хранить как хронологию изменений, так и только последнее изменение.

ObjectHistoryUtility.php

Утилита objecthistoryutility.phps будет работать только с теми объектами, у которых уже есть Factory. Переменная $InsertsOnly отвечает за режим работы. Если значение true, то в objectHistory будет хронология всех изменений, иначе - только последнее изменение.

Перейдем к интеграции с SaveAction.

Save<Class>Action.php

        /**
         * @var DateTime
         */
        private $ohCreatedAt;
 
        /**
         * @var User
         */
        private $user;
 
        /**
         * Before Action
         */
        protected function beforeAction() {
            $this->user        = AuthUtility::GetCurrentUser( 'User' );
            $this->ohCreatedAt = Request::getDateTime( 'ohCreatedAt' );
 
            // initialize ohCreatedAt
            if ( !$this->action && !$this->ohCreatedAt && $this->originalObject  ) {
                $this->ohCreatedAt = DateTimeWrapper::Now();
            }
 
            Response::setParameter( 'ohCreatedAt', $this->ohCreatedAt );
        }

В данном куске кода мы определили переменные user(текущий пользователь VT) , ohCreatedAt (дата открытия страницы редактирования)

eaze/samples/одновременное_редактирование_объектов.1353676775.txt.gz · Последние изменения: 2012/11/23 17:19 — sergeyfast