2014-10-09 2 views
-2

Меня задавали этот вопрос много раз и прослушивают меня надолго.Использование весенних транзакций с несколькими потоками

У нас есть класс обслуживания с 3 методами DAO, обновляющими 3 разных таблицы. Дизайн таков, что обновление ко всем трем таблицам должно быть атомарным. У меня есть 3 потока, вызывающих мой класс обслуживания отдельно и для каждого обновления метода DAO, Как использовать транзакции Spring или любой менеджер транзакций, чтобы поддерживать все потоки (операции) под одной транзакцией? Любые идеи или указатели на документацию? Спасибо!

+0

Возможный дубликат [Как использовать весеннюю транзакцию в многопоточном режиме] (http://stackoverflow.com/questions/10407301/how-to-use-spring-transaction-in-multithread) –

+0

Я думаю, что это поможет вам. [Весеннее управление транзакциями по нескольким потокам] (https://dzone.com/articles/spring-transaction-management-over-multiple-thread-1) –

ответ

0

Способ службе следует быть тот, который запускает транзакции

Service Метод

public class Service{ 
// define dao1,dao2,dao3 
@Transactional 
public someMethod(){ 
    dao1.someUpdate(); 
    dao2.someUpdate(); 
    dao3.someUpdate(); 
} 
} 

Dao1.class

public class Dao1{ 

     @Transactional (propagation = Propagation.MANDATORY) 
     public someUpdate(){ 

     } 
    } 

Аналогичным образом Dao2 и Dao3

someUpdate() будет использовать транзакцию, запущенную someMethod() из Service.c lass

+0

Спасибо за ваш ответ. Если я правильно понимаю ваше решение, три метода dao управляются одним потоком, который вызывает метод somemethod() в trasanction. Моя проблема состоит в том, чтобы выполнить три метода отдельно (одновременно), используя 3 потока. Любые предложения? – Dibjot

0

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

Примера код код в отдельных нитях

@Transactional(rollbackFor = Exception.class) 
public void saveData(Product product, ProductStatusObject productStatusObject) throws Exception { 
    productDao.persist(product); 
    if(product.getId() == 5) { 
     productStatusObject.updateCounter(false); 
    } else { 
     productStatusObject.updateCounter(true); 
    } 
    if(!productStatusObject.getStatus()) { 
     throw new Exception(); 
    } 
} 

Кодекса в общем классе частного конечный ИНТ totalThreads;

private int executedThreads = 0; 
private Boolean finalStatus = true; 

public ProductStatusObject(int totalThreads) { 
    this.totalThreads = totalThreads; 
} 

public synchronized void updateCounter(Boolean threadStatus) throws InterruptedException { 
    executedThreads ++; 
    if(!threadStatus) { 
     this.finalStatus = false; 
    } 
    if(totalThreads == executedThreads) { 
     notifyAll(); 
    } else { 
     wait(); 
    } 

} 

public synchronized Boolean getStatus() { 
    return finalStatus; 
} 

Здесь условие отказа - если какой-либо поток сохраняет данные с идентификатором 5, все потоки откатываются от их кода. Else все удастся