Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / Механизм транзакций. Spring MVC. / 25 сообщений из 30, страница 1 из 2
14.08.2012, 01:58:55
    #37915319
tepka
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Механизм транзакций. Spring MVC.
Коллеги, Ай нид Хелп,

Есть два чудесных метода на уровне Service, один из которых выполняется по расписанию:
Код: java
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.
@Scheduled(fixedDelay= 60000)
@Transactional
    public void doProcessing(){
        List<PostingScheduleEntity> postingScheduleList = postingDAO.getAllPostingSchedule();
        if (postingScheduleList.size()>0) {
            for(int i=0;i<postingScheduleList.size();i++){
               try{
                   postingSchedule(postingScheduleList.get(i));
               }catch(Exception ex){
                   byte error = 3;
                   postingScheduleList.get(i).setStatus(error);
                   postingDAO.saveOrUpdate(postingScheduleList.get(i));
               }
            }
        }            
    }

@Transactional
    public void postingSchedule(PostingScheduleEntity postingScheduleEntity) throws Exception{        
        Publication publication = new Publication(postingScheduleEntity);
        if (publication.isPublish()){
            byte success = 1;
            postingScheduleEntity.setStatus(success);
            postingDAO.saveOrUpdate(postingScheduleEntity);
        }else {
            byte failed = 2;
            postingScheduleEntity.setStatus(failed);
            postingDAO.saveOrUpdate(postingScheduleEntity);
        }
    }


Проблема в том, что есть так же метод postingSchedule(postingScheduleList.get(i)); Который выполняется в рамках одной и той же транзакции метода doProcessing();
Кагбэ сделать так чтобы метод postingSchedule открывал свою транзакцию(т.е. новую), и по успешному выходу из метода, commit'ил все наделанные за собой дела?

PS.
Мне почему то, кажется, что данное поведение должен обеспечивает атрибут propagation т.е. нужно заменить @Transactional на @Transactional(propagation = Propagation.REQUIRES_NEW) у метода doProcessing(). Но я так пробовал - не работает. Т.е. пока doProcessing() не закончит свои дела коммитов в postingSchedule не появляется.
...
Рейтинг: 0 / 0
14.08.2012, 02:35:11
    #37915325
Лагман
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Механизм транзакций. Spring MVC.
tepka,
а как вы наблюдаете появление коммитов?

алсо, maxximum indus mode:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
 
        if (publication.isPublish()){
            byte success = 1;
            postingScheduleEntity.setStatus(success);
            postingDAO.saveOrUpdate(postingScheduleEntity);
        }else {
            byte failed = 2;
            postingScheduleEntity.setStatus(failed);
            postingDAO.saveOrUpdate(postingScheduleEntity);
        }



Сделайте хотябы так штоле
Код: java
1.
2.
3.
4.
5.
            
	byte status = publication.isPublish() ? 1 : 2;

        postingScheduleEntity.setStatus(status);
        postingDAO.saveOrUpdate(postingScheduleEntity);
...
Рейтинг: 0 / 0
14.08.2012, 02:52:43
    #37915329
tepka
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Механизм транзакций. Spring MVC.
Лагманtepka,
а как вы наблюдаете появление коммитов?

Объект PostingScheduleEntity (postingScheduleList.get(i)) - это одна строка в табличке из нескольких колонок. Среди колонок есть колонка - статус (который я и меняю postingScheduleList.get(i).setStatus(statusId))

А перед выходом из метода doProcessing() ставлю брэкпоинт и смотрю в базе SELECT'ом (Toad или pl/sql Developer) в абсолютно новой сессии к базе.
...
Рейтинг: 0 / 0
14.08.2012, 09:32:14
    #37915450
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Механизм транзакций. Spring MVC.
tepka,
какой профит вы хотите получить от вложенной транзакции?
...
Рейтинг: 0 / 0
14.08.2012, 09:53:16
    #37915475
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Механизм транзакций. Spring MVC.
tepkaМне почему то, кажется, что данное поведение должен обеспечивает атрибут propagation т.е. нужно заменить @Transactional на @Transactional(propagation = Propagation.REQUIRES_NEW) у метода doProcessing(). Но я так пробовал - не работает. Т.е. пока doProcessing() не закончит свои дела коммитов в postingSchedule не появляется.
Всё верно. Но во-первых REQUIRES_NEW (или даже NESTED) должен стоять у postingSchedule. Во-вторых это всё равно не отработает так как оба метода у вас в одном классе. Транзакции спринг обеспечивает оборачивая классы в прокси. Но когда один метод класса вызывает другой метод того же класса, то вызов идёт мимо прокси и спринг никак не может его перехватить и обработать.

Направление мысли у вас правильное. Нужно использовать Propagation. Но класс стоит разбить на отдельные. Один будет отвечать только за scheduled задачи. Второй за саму обработку. Тогда управление транзакциями будет работать без проблем.
Можно, конечно и по-извращатся, вызывая вместо this.postingSchedule() этот же метод но у проксированого бина полученого из контекста.
...
Рейтинг: 0 / 0
14.08.2012, 13:28:03
    #37915776
tepka
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Механизм транзакций. Spring MVC.
Petro123какой профит вы хотите получить от вложенной транзакции?
не очень понял вопроса) но отвечу) Коммиты хочу получить от вложенной транзакции)

BlazkowiczНо когда один метод класса вызывает другой метод того же класса, то вызов идёт мимо прокси и спринг никак не может его перехватить и обработать.

ИМХО не совсем так.(хотя я могу и ошибаться) В доке написано, что аннотация @Transactional на методе, срабатывает по умолчанию (т.е. есть видимо какой то способ, не только по умолчанию) только, когда этот метод вызывается из вне. А не внутри класса.
BlazkowiczНаправление мысли у вас правильное. Нужно использовать Propagation. Но класс стоит разбить на отдельные.

Если класс разбить на два класса, то Propagation будет не нужен. Не ясно тогда назначение этого атрибута Propagation.
...
Рейтинг: 0 / 0
14.08.2012, 13:32:27
    #37915785
grasoff.net
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Механизм транзакций. Spring MVC.
tepkaИМХО не совсем так.(хотя я могу и ошибаться)всё именно так
тебе надо ещё раз перечитать первый абзац от Blazkowicz'а
...
Рейтинг: 0 / 0
14.08.2012, 13:40:57
    #37915799
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Механизм транзакций. Spring MVC.
tepkaКоммиты хочу получить от вложенной транзакции)
То есть NESTED? Или всё же просто независимая транзакция нужна? Тогда REQUIRES_NEW.

tepkaИМХО не совсем так.
Подкрепить стоит чем-то кроме своего имха.

tepkaВ доке написано, что аннотация @Transactional на методе, срабатывает по умолчанию (т.е. есть видимо какой то способ, не только по умолчанию)
Ну, как бы да. Методы все считаются как Propagation.REQUIRED - есть транзакиця, используется. Нет - создаётся новая. И можно ссылку на доку, которую вы используете. Уж больно вольная у вас трактовка.

tepkaтолько, когда этот метод вызывается из вне. А не внутри класса.
Ну, так а я о чем?

tepkaЕсли класс разбить на два класса, то Propagation будет не нужен. Не ясно тогда назначение этого атрибута Propagation.
Т.е. назначение не ясно, но вы твердо уверены что не нужен? По-умолчанию используется Propagation.REQUIRED. То что вы хотите это REQUIRES_NEW или NESTED. Какая именно из них вам нужнее, пока не ясно.
...
Рейтинг: 0 / 0
14.08.2012, 14:08:30
    #37915858
tepka
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Механизм транзакций. Spring MVC.
grasoff.netтебе надо ещё раз перечитать первый абзац от Blazkowicz'а
В оригинале звучит так:
In proxy mode (which is the default) , only external method calls coming in through the proxy are intercepted. This means that self-invocation, in effect, a method within the target object calling another method of the target object, will not lead to an actual transaction at runtime even if the invoked method is marked with @Transactional.
Сиё я могу интерпретировать так:
1) Что есть еще какой то способ по мимо proxy mode.
2) Аннотация @Transactional имеет смысл быть только у внешних методов. Т.е. если она будет стоять у внутренних методов класса она будет просто проигнорирована. Т.е. фраза "REQUIRES_NEW (или даже NESTED) должен стоять у postingSchedule" от Blazkowicz не имеет смысла. Так как атрибут propagation ставится у аннотации Transactional внутреннего метода.

А так же я все таки попробовал поставить Propagation.REQUIRES_NEW у метода postingSchedule и это не помогло. Пока doProcessing() не закончит свою работу, коммиты (postingDAO.saveOrUpdate(postingScheduleEntity)) внутри postingSchedule не появляются.

PS. Я не ставлю под сомнение авторитет Blazkowicz это великий человек. Он мне много раз помогал. Но я просто хочу разобраться с какой целью придумали Propagation, если он не работает.
...
Рейтинг: 0 / 0
14.08.2012, 14:17:02
    #37915888
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Механизм транзакций. Spring MVC.
tepkaPetro123какой профит вы хотите получить от вложенной транзакции?
не очень понял вопроса) но отвечу) Коммиты хочу получить от вложенной транзакции)
переведу:
- зачем коммиты?
Если не делать вложенную (всё в одной). то и коммит не нужен (старт тоже).
"Лечение перхоти гильотиной"

Или препод задал?
...
Рейтинг: 0 / 0
14.08.2012, 14:19:26
    #37915894
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Механизм транзакций. Spring MVC.
tepkaНо я просто хочу разобраться с какой целью придумали Propagation, если он не работает.
ok. Понятно. Сабж с целью изучения.
...
Рейтинг: 0 / 0
14.08.2012, 14:50:54
    #37915983
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Механизм транзакций. Spring MVC.
tepka1) Что есть еще какой то способ по мимо proxy mode.

В другом режим байт код модифицируется после компиляции, либо во время загрузки классов. Новый код добавляется непосредственно в методы. Тогда проблемы с внутренними вызовыми быть не должно. Т.к. AOP уже реализован в методах, и прокси не нужны.

tepka2) Аннотация @Transactional имеет смысл быть только у внешних методов.

Внутренний\внешний методы это не объективный атрибут метода. Это только способ, которым метод вызывается.

tepkaТ.е. если она будет стоять у внутренних методов класса она будет просто проигнорирована.

Не совсем. Просто вызов пойдёт мимо прокси, в которой реализован AOP. Можно вызвать тот же метод, использую ссылку на прокси. Метод от этого не перестанет быть "внутренним". Но АОП уже отработает нормально.

tepkaТ.е. фраза "REQUIRES_NEW (или даже NESTED) должен стоять у postingSchedule" от Blazkowicz не имеет смысла.

Выводы у тебя не адекватные. Я подробно изложил, почему это не будет работать в твоём случае и как эту проблему решить.

tepkaТак как атрибут propagation ставится у аннотации Transactional внутреннего метода.

Нет такого понятия как "внутренний метод". Есть понятие "внутренний вызов" - вызов метода внутри класса через ссылку this, мимо спринговой прокси, которая реализует AOP.

tepkaА так же я все таки попробовал поставить Propagation.REQUIRES_NEW у метода postingSchedule и это не помогло.

Удивительно. Наверное потоум что "вызов метода внутри класса через ссылку this идёт, мимо спринговой прокси, которая реализует AOP", о чем я уже раз 5й в этой теме пишу.

tepkaПока doProcessing() не закончит свою работу, коммиты (postingDAO.saveOrUpdate(postingScheduleEntity)) внутри postingSchedule не появляются.
Ещё раз объяснить почему?

tepkaНо я просто хочу разобраться с какой целью придумали Propagation, если он не работает.
Ну, вот почему сразу "он не работает". С чего ты решил, что Propagation не работает. Не работет Spring AOP когда он реализован через прокси а вызовы методов происходят мимо прокси. Что просто и логично. Это никак не связано с тем что не работает Propagation.
...
Рейтинг: 0 / 0
14.08.2012, 14:52:03
    #37915986
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Механизм транзакций. Spring MVC.
В целом, совет один. Отложи в сторону вопрос транзакций, и разберись с тем что такое АОП и как именно оно реализовано в Spring.
...
Рейтинг: 0 / 0
14.08.2012, 14:55:32
    #37915997
tepka
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Механизм транзакций. Spring MVC.
BlazkowiczТо есть NESTED? Или всё же просто независимая транзакция нужна? Тогда REQUIRES_NEW.

Да мне все равно какая транзакция, новая или не зависимая) Мне нужны коммиты во внутренним методе) А они есть как у NESTED так и у REQUIRES_NEW.

Цель же простая. Есть метод doProcessing в нём крутиться цикл. Который просто вызывает метод postingSchedule. И надо чтобы при выходе из postingSchedule делались коммиты. Суть в том, что цикл может крутиться очень долго, а объекты PostingScheduleEntity дёргаются еще и из другого места и так же по расписанию (в другой транзакции, вообще с другого апликейшен сервера), но по фильтру статуса. И пока статусы не про апдейтяться фиг, что дёрнется с базы.

BlazkowiczПодкрепить стоит чем-то кроме своего имха.

Цитата из доке выше.

BlazkowiczИ можно ссылку на доку, которую вы используете. Уж больно вольная у вас трактовка.

http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/transaction.html
и её перевод
http://www.lexvit.dn.ua/articles/?art_id=springtrn2_mht201007207552

Blazkowicztepkaтолько, когда этот метод вызывается из вне. А не внутри класса.
Ну, так а я о чем?

Да я про то что, ты описал принцип работы только proxy mode. А по мимо него есть другие mode. А так же про то что аннотацию Transactional можно ставить только на внешние методы. Не имеет смысл вешать REQUIRES_NEW на метод postingSchedule. Он все равно будет про игнорирован (хотя я могу и ошибаться я это читал на каком то буржуйском форуме, уже найти не могу)

BlazkowicztepkaЕсли класс разбить на два класса, то Propagation будет не нужен. Не ясно тогда назначение этого атрибута Propagation.
Т.е. назначение не ясно, но вы твердо уверены что не нужен?

Назначение его ясно) Не ясно почему он не работает)
...
Рейтинг: 0 / 0
14.08.2012, 15:01:46
    #37916021
tepka
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Механизм транзакций. Spring MVC.
ладно)
пойду думать над сказанным от Blazkowicz)
Чего то я не догоняю точно)
...
Рейтинг: 0 / 0
14.08.2012, 15:57:56
    #37916204
Йуный джавистЪ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Механизм транзакций. Spring MVC.
Я думал, что для класса
Код: java
1.
2.
3.
4.
5.
class FooService{
  public void foostuff(){
    // do some business logic
  }
}


Спринг генерит
Код: java
1.
2.
3.
4.
5.
6.
7.
class FooServiceSpringMagicProxy extends FooService{
  public void foostuff(){
     //do some magic
     super.foostuff();
     //do some more magic
  }
}


В таком варианте проблем не должно быть
...
Рейтинг: 0 / 0
14.08.2012, 16:05:48
    #37916219
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Механизм транзакций. Spring MVC.
tepkaЧего то я не догоняю точно)
С английским текстом тоже нужно поточнее обращатся.
external method call это не "внешний метод", это "внешний вызов метода".
Что любопытно в указанном переводе это тоже достаточно корректно отражено. А у тебя появились какие-то внутренние и внешние методы.
...
Рейтинг: 0 / 0
14.08.2012, 16:10:36
    #37916242
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Механизм транзакций. Spring MVC.
Йуный джавистЪЯ думал, что для класса
Код: java
1.
2.
3.
4.
5.
class FooService{
  public void foostuff(){
    // do some business logic
  }
}


Спринг генерит
Код: java
1.
2.
3.
4.
5.
6.
7.
class FooServiceSpringMagicProxy extends FooService{
  public void foostuff(){
     //do some magic
     super.foostuff();
     //do some more magic
  }
}


В таком варианте проблем не должно быть
Как раз проблема в том, что если вызывать FooService.foostuff(), то прокси про это никогда ничего не узнает. Что и происходит у автора темы.
А вот если настроить AspecJ weaving, то do some magic будет добавлен непосредственно в FooService. Тогда проблемы стем чтобы получить ссылку на прокси не будет. Так как не будет и самой прокси.
...
Рейтинг: 0 / 0
14.08.2012, 16:39:08
    #37916323
tepka
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Механизм транзакций. Spring MVC.
Blazkowicz А у тебя появились какие-то внутренние и внешние методы.
Я выразился не точно. Для меня просто внешний метод = внешнему вызову метода. Я думал для всех это очевидно, так как нет такого понятия внешний метод.
...
Рейтинг: 0 / 0
14.08.2012, 16:52:48
    #37916340
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Механизм транзакций. Spring MVC.
tepka,
ты хочешь убрать изоляцию транзакций (невидимость изменений между незакоммиченными)?
Т.е. статус-колонка была видна всем до коммита-конца внешней транзакции doProcessing?
...
Рейтинг: 0 / 0
14.08.2012, 16:54:17
    #37916344
tepka
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Механизм транзакций. Spring MVC.
Petro123tepka,
Т.е. статус-колонка была видна всем до коммита-конца внешней транзакции doProcessing?
ну да
...
Рейтинг: 0 / 0
14.08.2012, 16:59:44
    #37916351
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Механизм транзакций. Spring MVC.
tepka,
но ведь неудобно:
- в коде любой программист видит вложенный код, и понимает его как ОДНУ транзакцию. И тут такие фокусы
- невозможно будет откатить внешнюю корректно. Статусы будут неверные
- ещё куча ограничений для
http://ru.wikipedia.org/wiki/%D0%90%D0%B2%D1%82%D0%BE%D0%BD%D0%BE%D0%BC%D0%BD%D1%8B%D0%B5_%D1%82%D1%80%D0%B0%D0%BD%D0%B7%D0%B0%D0%BA%D1%86%D0%B8%D0%B8

Если код - разные автономные транзакции с коммитом, то и разбей его семантически на разные куски (классы и т.д.).
...
Рейтинг: 0 / 0
14.08.2012, 17:02:22
    #37916357
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Механизм транзакций. Spring MVC.
Спринг конечно может перемешать всю логику кода через модификацию его. Но как потом прогеру врубаться в логику? IMHO
...
Рейтинг: 0 / 0
14.08.2012, 17:12:25
    #37916372
tepka
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Механизм транзакций. Spring MVC.
Petro123- в коде любой программист видит вложенный код, и понимает его как ОДНУ транзакцию. И тут такие фокусы

Так вот я по сути и хочу разделить ОДНУ транзакцию на две) А как это сделать, не поделив два метода на два класса не знаю.
Одна транзакция читает:
List<PostingScheduleEntity> postingScheduleList = postingDAO.getAllPostingSchedule();
Она получает список job'ов которые надо публиковать.
Вторая транзакция пишет:
postingSchedule(postingScheduleList.get(i));
Он апдейтит статусы на основе некоторой логики.

Petro123- невозможно будет откатить внешнюю корректно. Статусы будут неверные

В внешная транзакция она читатель. Её не надо откатывать.

Petro123Если код - разные автономные транзакции с коммитом, то и разбей его семантически на разные куски (классы и т.д.).

Класс, в котором один метод... это конечно здорово. Но дух фен шея не сможет спокойно передвигать в пакете в котором все завалено классами с одним методом.
...
Рейтинг: 0 / 0
14.08.2012, 17:32:37
    #37916414
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Механизм транзакций. Spring MVC.
tepka,
ты приведи структуру табличек и замысел. Наверняка есть более элегантное решение, чем один вариант - в лоб.
Понятно, что спагетти код никто не хочет.
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / Механизм транзакций. Spring MVC. / 25 сообщений из 30, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]