1

Ниже приведен фрагмент нашего исходного кода ...Hibernate JPA несколько веб-служб обновляющие ту же таблицу

@transactional 
public void doSomething(){ 
    User user = (set up user fields) 
    userDao.merge(user); //update USER table 
    //call another web service which also updates USER table 
    //do other processes 
} 

Проблема, обновление с другого веб-службы переопределяется обновления из userDao.merge после него не выполняет транзакцию слияния до тех пор, пока не будет выполнен транзакционный метод.

Как вы справляетесь с такой ситуацией? Я хочу как обновление от userdao.merge, так и обновление, сделанное другой веб-службой, которая будет сделана в записи.

+0

Я предполагаю, что вы не используете JTA через приложения для синхронизации транзакции? Другими словами, это два отдельных приложения, которые просто управляют одной и той же строкой базы данных одновременно со своими собственными транзакциями. – Naros

+0

Я думаю, что лучший вопрос был бы, вас беспокоит, не удастся ли другому веб-сервису, даже несмотря на успешное создание веб-сервиса? – Naros

+0

Я не использую его. Это то, что мне нужно сделать? Как это реализовать? –

ответ

0

Поместите первое обновление пользователя в новом транзакционного метода обозначенному распространения REQUIRES_NEW:

@Transactional 
public void doSomething(){ 

    updateUser(); 

    //call another web service which also updates USER table 
    //do other processes 
} 

@Transactional(propagation = Propagation.REQUIRES_NEW) 
public void udateUser(){ 

User user = (set up user fields) 
    userDao.merge(user); //update USER table 

} 

Перед вызовом WebService внутренней транзакции будут поручены и результаты видны WebService. Просто имейте в виду, если веб-сервис не работает. Первое обновление пользователя не будет отменено.

+0

Итак, вы говорите, откат может быть сделан только вручную в этой ситуации? @Transactional не может обрабатывать его автоматически? –

+0

Это решение не будет работать. Проблема, с которой пользователь сталкивается, заключается в том, что вызов другого веб-службы должен произойти * после того, как * исходный метод 'doSomething()' отправил слияние в базу данных. – Naros

+0

@Naros: так действительно ли есть решение? или эта логика у нас, когда две веб-службы обновляются, одна и та же таблица не является хорошей практикой? –

0

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

Если вам требуются атомные транзакции, что означает, что оба обновления происходят, или оба они этого не делают, вам необходимо использовать распределенные транзакции на основе JTA для ваших двух приложений. Серверы приложений предоставляют этот готовый продукт, вам просто нужно настроить приложения для его использования.

неатомарную решение будет вызывать с помощью интерфейса Спринга TransactionSynchronization предложить #afterCommit() обратного вызова:

@Transactional 
public void doSomething() { 
    // do stuff 
    userDao.merge(user); 

    TransactionSynchronizationManager.registerSynchronization(
    new TransactionSynchronization() { 
     void afterCommit() { 
     // call to second service somehow 
     } 
    } 
); 
} 

Как вы называете, что вторая услуга полностью зависит от вас. Вы можете отправить сообщение JMS с триггером в очередь, которую прослушивает вторая веб-служба, или вы можете напрямую вызвать эту вторую веб-службу.

Критическая часть здесь заключается в том, что вызов либо брокеру, либо второму веб-сервису должен быть отказоустойчивым, поэтому гарантируйте, что возможный контракт согласованности.

+0

если исключение происходит при вызове второй веб-службы, как вы откатываете назад? –

+0

Вам нужно настроить JTA, и для этого оба приложения подписываются на одну и ту же распределенную транзакцию. Весенняя документация описывает, как настроить распределенные транзакции JTA. – Naros

Смежные вопросы