[Spring] @Scheduled и @Transactional
От: InstantI Украина  
Дата: 15.10.11 11:30
Оценка:
Доброго времени суток. В приложении на Spring + Hibernate мне понадобилось выполнять некую работу по расписанию, сделал по туторилам так:
@Service
public class ServerScanner implements RequestHandler
{    
    @Scheduled(fixedRate = 60000)
    public void process()
    {
        doWork();
    }
    
    @Transactional
    private void doWork()
    {
        // Some code with DAO here
    }
    
    @Autowired
    private ServerDAO serverDAO;
}

В методе doWork() у меня есть обращение к полям с ленивой инициализацией, поэтому мне нужно, что бы открывалась сессия Hibernate'a во время выполнения этого метода.
Вот, что получается при срабатывании таймера. При этом, аналогичный код, помещенный в контроллер, работает нормально.
org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here

Попробовал добавить такую строчку в конфиг Hibernate'a:
<prop key="hibernate.current_session_context_class">thread</prop>

Теперь вылетает это:
org.hibernate.HibernateException: createQuery is not valid without active transaction

Подскажите, как правильно решать эту задачу?
Re: [Spring] @Scheduled и @Transactional
От: PZI  
Дата: 15.10.11 11:50
Оценка: 3 (1)
Здравствуйте, InstantI, Вы писали:

У вас doWork вызывается не через спринговую прокси. Сделайте какой нить ScheduledServiceWorker и заинжектите туда ServerScanner. Тогда вызов doWork пойдет через прокси. Можно еще через контекст получить ссылку на свою прокси, но имхо это как то не красиво.
Re[2]: [Spring] @Scheduled и @Transactional
От: InstantI Украина  
Дата: 15.10.11 12:51
Оценка:
Здравствуйте, PZI, Вы писали:

PZI>У вас doWork вызывается не через спринговую прокси. Сделайте какой нить ScheduledServiceWorker и заинжектите туда ServerScanner. Тогда вызов doWork пойдет через прокси. Можно еще через контекст получить ссылку на свою прокси, но имхо это как то не красиво.


Попытался сделать как Вы объяснили.
@Service
public class ScheduledServiceWorker
{
    @Scheduled(fixedRate = 60000)
    public void process()
    {
        scanner.process();
    }   
    
    @Autowired
    private ServerScanner scanner;
}

А вот сам ServerScanner
@Service
public class ServerScanner
{    
    @Transactional
    public void process()
    {
        // Some code here.        
    }

Теперь перестало запускаться совсем
org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [net.mydomain.service.impl.ServerScanner]

Может у меня что-то в конфиге не правильно?
context:annotation-config />
<task:scheduler id="taskScheduler" />
<task:executor id="taskExecutor" pool-size="1" />
<task:annotation-driven executor="taskExecutor" scheduler="taskScheduler" />
<tx:annotation-driven />    
     
<context:component-scan base-package="net.mydomain.service" />    
<context:component-scan base-package="net.mydomain.dao" />   

<import resource="data.xml" />
Re[3]: [Spring] @Scheduled и @Transactional
От: PZI  
Дата: 15.10.11 14:39
Оценка:
Здравствуйте, InstantI, Вы писали:

II>Здравствуйте, PZI, Вы писали:


В ServerScanner случайно нет депенденси на самого себя?
Re[4]: [Spring] @Scheduled и @Transactional
От: PZI  
Дата: 15.10.11 14:46
Оценка: 3 (1)
Здравствуйте, PZI, Вы писали:

PZI>Здравствуйте, InstantI, Вы писали:


II>>Здравствуйте, PZI, Вы писали:


PZI>В ServerScanner случайно нет депенденси на самого себя?


Ну и сейчас лень конечно читать доки, будет ли спринг генерить прокси на классы без интерфейсов, но без интерфейсов как то не красиво.
Re[5]: [Spring] @Scheduled и @Transactional
От: InstantI Украина  
Дата: 15.10.11 16:07
Оценка:
Здравствуйте, PZI, Вы писали:

PZI>Ну и сейчас лень конечно читать доки, будет ли спринг генерить прокси на классы без интерфейсов, но без интерфейсов как то не красиво.


Сделал через интерфейс, помогло, большое спасибо!
Re: [Spring] @Scheduled и @Transactional
От: Аноним  
Дата: 18.10.11 18:31
Оценка:
Здравствуйте, InstantI, Вы писали:
II>Подскажите, как правильно решать эту задачу?
1. Поставить аннотацию Transactional на метод process, хотя я не уверен может и не сработать.
2. Если первое не поможет, создать класс для джоба, туда притянуть сервис и дергать метод сервиса оттуда это 100% гарантия. Кстати в этот класс джоба можно
будет притянуть все сервисы методы которых нужно дергать по расписанию, так хоть какой-то порядок будет, все работы в одном месте.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.