printObj(pObj);

}

// Prints out the basic information about the object pointed

// to by pObj.

//

void

printObj(const AcDbObject* pObj)

{

if (pObj == NULL)

{

acutPrintf("(NULL)");

return;

}

AcDbHandle objHand;

char handbuf[17];

// Get the handle as a string.

//

pObj->getAcDbHandle(objHand);

objHand. getIntoAsciiBuffer(handbuf);

acutPrintf(

"\n (class==%s, handle==%s, id==%lx, db==%lx)",

pObj->isA()->name(), handbuf,

pObj->objectId().asOldId(), pObj->database());

}

// Document swapping functions

//

void

AsdkDocReactor::documentToBeActivated(AcApDocument *pDoc)

{

gpAsdkAppDocGlobals->setGlobals(pDoc);

}

void

AsdkDocReactor::documentCreated(AcApDocument *pDoc)

{

gpAsdkAppDocGlobals->setGlobals(pDoc);

}

void

AsdkDocReactor::documentToBeDestroyed(AcApDocument *pDoc)

{

gpAsdkAppDocGlobals->removeDocGlobals(pDoc);

}

AsdkPerDocData::AsdkPerDocData(AcApDocument *pDoc)

{

m_pDoc = pDoc;

m_pNext = NULL;

m_EntAcc = 0;

m_pDbr = NULL;

}

AsdkAppDocGlobals::AsdkAppDocGlobals(AcApDocument *pDoc)

{

m_pData = m_pHead = NULL;

m_pDocReactor = new AsdkDocReactor();

acDocManager->addReactor(m_pDocReactor);

}

// Iterate through the list until the documents’s global data is

// found. If it is not found, create a new set of document globals.

//

void

AsdkAppDocGlobals::setGlobals(AcApDocument *pDoc)

{

AsdkPerDocData *p_data = m_pHead, *prev_data = m_pHead;

while (p_data!= NULL)

{

if (p_data->m_pDoc == pDoc)

НЕ нашли? Не то? Что вы ищете?

{

m_pData = p_data;

break;

}

prev_data = p_data;

p_data = p_data->m_pNext;

}

if (p_data == NULL)

{

if (m_pHead == NULL)

m_pHead = m_pData = new AsdkPerDocData(pDoc);

else

prev_data->m_pNext = m_pData = new AsdkPerDocData(pDoc);

}

}

// Delete the globals associated with pDoc.

//

void

AsdkAppDocGlobals::removeDocGlobals(AcApDocument *pDoc)

{

AsdkPerDocData *p_data = m_pHead, *prev_data = m_pHead;

while (p_data!= NULL)

{

if (p_data->m_pDoc == pDoc)

{

if (p_data == m_pHead)

m_pHead = p_data->m_pNext;

else

prev_data->m_pNext = p_data->m_pNext;

if (m_pData == p_data)

m_pData = m_pHead;

delete p_data;

break;

}

prev_data = p_data;

p_data = p_data->m_pNext;

}

}

// Delete all the doc globals in the list (recursively).

//

void

AsdkAppDocGlobals::removeAllDocGlobals(AsdkPerDocData *p_target)

{

if (p_target == NULL)

return;

if (p_target->m_pNext!= NULL)

removeAllDocGlobals(p_target->m_pNext);

if (p_target->m_pDbr!= NULL)

{

acdbHostApplicationServices()->

workingDatabase()->removeReactor(p_target->m_pDbr);

delete p_target->m_pDbr;

p_target->m_pDbr = NULL;

}

delete p_target;

}

// Application was unloaded - delete everything associated with this

// document.

//

void AsdkAppDocGlobals::unload()

{

acDocManager->removeReactor(m_pDocReactor);

delete m_pDocReactor;

removeAllDocGlobals(m_pHead);

m_pHead = m_pData = NULL;

}

long &

AsdkAppDocGlobals::entityCount()

{

return m_pData->m_EntAcc;

}

void

AsdkAppDocGlobals::incrementEntityCount()

{

m_pData->m_EntAcc++;

}

void

AsdkAppDocGlobals::decrementEntityCount()

{

m_pData->m_EntAcc--;

}

AsdkDbReactor *

AsdkAppDocGlobals::dbReactor()

{

return m_pData->m_pDbr;

}

void

AsdkAppDocGlobals::setDbReactor(AsdkDbReactor *pDb)

{

m_pData->m_pDbr = pDb;

}

// Adds a reactor to the database to monitor changes.

// This can be called multiple times without any ill

// effects because subsequent calls will be ignored.

//

void

watchDb()

{

AsdkDbReactor *pDbr;

if (gpAsdkAppDocGlobals->dbReactor() == NULL)

{

pDbr = new AsdkDbReactor();

gpAsdkAppDocGlobals->setDbReactor(pDbr);

acdbHostApplicationServices()->workingDatabase()->addReactor(pDbr);

acutPrintf(

" Added Database Reactor to "

"acdbHostApplicationServices()->workingDatabase().\n");

}

}

// Removes the database reactor.

//

void

clearReactors()

{

AsdkDbReactor *pDbr;

if ((pDbr = gpAsdkAppDocGlobals->dbReactor()) != NULL)

{

acdbHostApplicationServices()->workingDatabase()->removeReactor(pDbr);

delete pDbr;

gpAsdkAppDocGlobals->setDbReactor(NULL);

}

}

// ObjectARX entry point function

//

AcRx::AppRetCode

acrxEntryPoint(AcRx::AppMsgCode msg, void* appId)

{

switch (msg) {

case AcRx::kInitAppMsg:

acrxUnlockApplication(appId);

acrxRegisterAppMDIAware(appId);

gpAsdkAppDocGlobals = new AsdkAppDocGlobals(curDoc());

gpAsdkAppDocGlobals->setGlobals(curDoc());

acedRegCmds->addCommand("ASDK_NOTIFY_TEST",

"ASDK_WATCH",

"WATCH",

ACRX_CMD_TRANSPARENT,

watchDb);

acedRegCmds->addCommand("ASDK_NOTIFY_TEST",

"ASDK_CLEAR",

"CLEAR",

ACRX_CMD_TRANSPARENT,

clearReactors);

break;

case AcRx::kUnloadAppMsg:

if (gpAsdkAppDocGlobals!= NULL)

{

gpAsdkAppDocGlobals->unload();

delete gpAsdkAppDocGlobals;

gpAsdkAppDocGlobals = NULL;

}

acedRegCmds->removeGroup("ASDK_NOTIFY_TEST");

break;

}

return AcRx::kRetOK;

}

Глава17. Управление транзакцией

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

Транзакции могут быть вложены и могут быть закончены или прерван на усмотрение клиента. Эта модель может использоваться в конъюнкции с регулярным " в объект" открытый и близкий механизм, описанный в главе 5, “ Объекты Базы данных. ”

§  Краткий обзор Управления Транзакции

§  Менеджер Транзакции

§  Вложение транзакций

§  Границы Транзакции

§  Получение Указателей на Объекты в Транзакции

§  Недавно Созданные Объекты и транзакции

§  Совершают разовые Руководящие принципы

§  Отмена и транзакции

§  Смешивание Модели Транзакции с Открытым и Близким Механизмом

§  транзакции и Графическое порождение

§  Реакторы Транзакции

§  Пример Вложенных транзакций

Краткий обзор управления транзакциями

Операционная модель формирует множественные операции на множественных объектах несколькими клиентами, поскольку одна атомная операция вызвала транзакцию. Внутри операционной границы, клиенты могут получить объектные указатели от объекта IDs. Объектные указатели, таким образом полученные имеют силу, пока транзакция не закончена или прервана клиентом. Если транзакция закончена успешно, операции на объектах совершены{*переданы*}. Если транзакция прервана, операции на объектах отменены.

Действие на объектах, использующих эту парадигму имеет несколько преимуществ по регулярному открытому и близкому механизму, описанному в главе 5, “ Объекты Базы данных. ” Открытый и близкий механизм подходящий для простых операций на единственном{*отдельном*} объекте или маленькой группе объектов. Однако, имеются некоторые ограничения на открывающиеся объекты этот путь. Например, если объект открытый для чтения, Вы не можете открывать это для записи в то же самое время. Если объект открытый для записи, Вы не можете открывать это для записи второй раз. Для списка ошибок конфликта, связанных с открытым и близким механизмом, см. главу 5, “ Объекты Базы данных. ” Операционная модель более снисходительна, и получение объектных указателей от объекта IDs для специфического режима обычно преуспевает, если объект связан с транзакцией.

В зависимости от вашего приложения, могут иметься другие недостатки к использованию открытого и закрывать механизм. Если ваше приложение открывает и закрывает тот же самый объект неоднократно в ходе одной операции — например, команда — вы будете нести серьезные неэффективность из-за этого множителя, открывает и закрывается. Множество отнимающих много времени операций связано с закрытием объекта. Если Вы открываете объект для записи, измените это, и затем закройтесь, это, записи отмены модификации совершено{*передано*} файлу отмены, графика для объекта сгенерирована, и уведомления обстреляны. Все эти операции

Выполненный каждый раз объект закрыт. Если Вы проводите вашу операцию и получаете указатель на объект, используя транзакцию, все действия, упомянутые выше случаются только однажды, в конце транзакции. Результат - улучшенная эффективность и меньший файл отмены, потому что число записей, входящих в файл отмены уменьшен.

Также, если Вы имеете сложную сеть, где объекты обращаются{*относятся*} к друг другу объектом ID, Вы хотите быть способными получить указатель на объект в любом модуле вашей программы без того, чтобы волноваться, если другой модуль или другое приложение открывают тот объект. Эти действия - только возможное использование операционная модель потому что операции группы транзакций и позволяют получать указатели от объекта IDs поперек границ модуля.

Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132