Общий принцип
Контроль транзакций осуществляется на уровне релизации сценария / маршрута ИР.
Реализация сценария / маршрута для обработки каждого объекта (сигнал, сообщение, передача в систему получателя и прочее) создает отдельную траназкцию, для обеспечания непрерывной обработки всех операций движения сообщения по маршруту в случае возникновения исключительных ситуаций обработки конткретного объекта на любом из этапов передачи.
Техническая спецификация
Транзакционность выборок / получения коллекций обеспечивается использованием CollectionService
Передача управления транзакциями
Для передачи управления транзакциями на уровень управления реализации ИР, платформенная задача объявляется с нотацией taskTransactionalManagement = true
Блок кода |
---|
|
@ScheduleTask(name = "CorpRouteInputOutput", taskTransactionalManagement = true,minute = "*/1", active = true, timeout = 10, allNodes = true, type= SheduleType.Singleton)
public class CorpRouteInputOutput implements ScheduleTaskHandle { |
Варианты реализации
Вызов транзакционного когда с помощью TransactionalContext
В СМ-И реализован интерфейс TransactionalContext реализующий вызов кода в транзакционной обертки
Блок кода |
---|
language | java |
---|
title | Пример 1 |
---|
|
public class CorpRouteInputOutput implements ScheduleTaskHandle {
@Autowired
TransactionalContext transactionalContext;
@Override
public String execute(EJBContext ejbContext, SessionContext sessionContext, ScheduleTaskParameters parameters) throws InterruptedException {
transactionalContext.executeInTransaction(()-> {
// обработка
});
return null;
}
} |
Блок кода |
---|
language | java |
---|
title | Пример 2 |
---|
|
public class CorpRouteInputOutput implements ScheduleTaskHandle {
@Autowired
TransactionalContext transactionalContext;
@Override
public String execute(EJBContext ejbContext, SessionContext sessionContext, ScheduleTaskParameters parameters) throws InterruptedException {
TransactionalContext.TransactionResult<String> example = transactionalContext.executeInTransaction(()->{
return "1";
});
System.out.println(example.executionResult());
return null;
}
} |
Автоматическое управление
Подключение транзакционности с использованием с Spring аннотации @Transactional
Блок кода |
---|
|
@Transactional(propagation = Propagation.REQUIRES_NEW)
public boolean processSignal() {
boolean result = false;
// обработка объекта
return result;
} |
Программное управление
Реализация этапа обработки
Для каждого этапа обработки объекта необходимо создать отдельную функцию, реализация которой полностью обернута в секцию try..catch
Внутри try..catch обработка объекта начинается с начала транзакции SessionContext.getUserTransaction().begin() и после всех операций завершается транзакция SessionContext.getUserTransaction().commit().
В области обработки исключения, выполняется откат транзации вызовом SessionContext.getUserTransaction().rollback() с проверкой открытости транзакции SessionContext.getUserTransaction().getStatus() == Status.STATUS_ACTIVE или Status.STATUS_MARKED_ROLLBACK
Примечание |
---|
|
Выход rollback необходимо оборачивать в try catch |
Блок кода |
---|
|
private boolean processSignal(SessionContext sessionContext) {
boolean result = false;
try {
sessionContext.getUserTransaction().begin();
// обработка объекта
sessionContext.getUserTransaction().commit();
} catch (Exception ex) {
// логирование ошибки
try {
if (sessionContext.getUserTransaction().getStatus() == sessionContext.STATUS_ACTIVE || sessionContext.getUserTransaction().getStatus() == sessionContext.STATUS_MARKED_ROLLBACK) {
sessionContext.getUserTransaction().rollback();
}
} catch (Exception ignoreEx) {
}
}
return result;
} |
3.4.
Реализация маршрута
Так как обработка каждого объекта является отдельной транзакцией, то при выполении интеграционного маршрута необходимо обрабтывать взведения флага отмены задания, получаемый методом: SessionContext.wasCancelCalled()
Проверка отмены выполнения задания необходимо выполнять перед началом транзакции, то есть перед обработкой каждого объекта и в случае устанволенного флага завершать выполнение без формирования ошибок.
Блок кода |
---|
|
public boolean executeRoute(SessionContext sessionContext) {
boolean result = true;
// получение коллекции объектов для обработки
for (Signal signal : signalCollection) {
if (!sessionContext.wasCancelCalled()) {
processSignal(signal, sessionContext);
} else {
return true;
}
}
// получение коллекции объектов для сообщений
for (Message message : message Collection) {
if (!sessionContext.wasCancelCalled()) {
processMessage(message , sessionContext);
} else {
return true;
}
}
return result;
} |