2015-12-11 6 views
0

У меня есть служба tomcat с пружинным основанием. Я использую сопоставление hibernate на основе аннотаций, и у меня есть несколько оштрафованных баз данных. Все ошаркированные базы данных имеют одинаковые таблицы, говорят студенты. Я хочу реализовать транзакцию на них с помощью аннотации @Transactional.Множественные оговоренные базы данных Операции спящего режима

@Autowired 
List<SessionFactory> sessionFactoryList; 

@Transactional 
public insertStudentBatch(List<Student> students) { 

} 

Теперь я хочу вставить целую партию. Если возникает какая-либо ошибка, я хочу, чтобы все они откатились. Каков наилучший способ сделать это? Могу ли я написать несколько квалификаторов TransactionManager, таких как @Transactional("txManager1", "txManager2")?

+1

Почему бы вам не попробовать, не попросив, можете ли вы попробовать? – innoSPG

+0

Не работает. Я спрашиваю, могу ли я настроить его так или иначе, чтобы работать. Когда я пытаюсь вставить в 2 БД с помощью @Transactional, он вставляется только в один из них. – Amit

ответ

1

Нет, к сожалению, весна @Transactional аннотация предназначена только для одного менеджера транзакций и не ведет себя в желании, которое вы описали.

Мне кажется, что вы, скорее всего, захотите, это транзакция JTA для фиксации 2PC, где вы в основном запускаете основную транзакцию JTA, а затем для каждого SessionFactory вы вызываете каждого из определенных менеджеров транзакций для своих осколков и выполняете свои операции.

@Service 
public class StudentBatchServiceImpl implements StudentBatchService { 
    @Autowired List<StudentService> studentServices; 
    @Transactional(value = "jtaTransactionManager") 
    public void storeStudents(List<Student> students) { 
    for(StudentService service : studentServices) 
     service.storeStudents(students); 
    } 
} 

public interface StudentService { 
    void storeStudents(List<Student> students); 
} 

public abstract AbstractStudentServiceImpl implements StudentService { 
    protected void storeStudents(EntityManager em, List<Student> students) { 
    for(Student student : students) { 
     em.persist(student); 
    } 
    } 
} 

@Service 
public class Shard1StudentServiceImpl extends AbstractStudentServiceImpl { 
    @PersistenceContext(name = "shard1") 
    private EntityManager entityManager; 
    @Override 
    @Transactional(value = "shard1TransactionManager") 
    public void storeStudents(List<Student> students) { 
    storeStudents(entityManager, students); 
    } 
} 

Там могут быть некоторые другие способы справиться с этим без 2PC совершить установку с JTA, но tyically в контейнере удалось сделок (например, JBoss, WebLogic, и т.д.); это был бы подход.

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

UPDATE

Если вы хотите, чтобы избежать необходимости создавать несколько реализаций класса осколок с подробной аннотацией, вы можете прибегнуть к конфигурации XML и имеют единственную реализацию класса:

<bean id="shard1" class="default.ShardStudentServiceImpl"> 
    <property name="entityManager" ref="shard1EntityManager" /> 
    <property name="transactionManager" ref="shard1TransactionManager" /> 
</bean> 

Единственное различие здесь вы должны определить свои 25 обрывов в XML, а затем вам нужно написать свой собственный код для запуска, фиксации и управления транзакцией внутри вашего класса ShardStudentServiceImpl.

Использование абстрактного базового класса в сочетании с аннотациями в конечных реализациях, показанных выше, мое обновление прибывает в тот же пункт назначения. Фактически, если вы посмотрите на spring-batch, вы заметите, что их пакетная конфигурация следует аналогичной предпосылке с указанием менеджера сущностей и менеджеров транзакций в качестве входных свойств для одного класса.

+0

Что имеется в виду - '// Каждый экземпляр здесь имеет свой собственный EntityManager/SessionFactory/PersistenceContext '? Если у меня 25 баз данных, мне нужно его реализовать 25 раз? Не могли бы вы сделать это более понятным? – Amit

+0

Да, у вас будет несколько реализаций 'AbstractStudentServiceImpl', потому что каждая реализованная служба описывает контракт между экземпляром контекста persistence и конкретным экземпляром менеджера транзакций. См. Мое обновление. – Naros

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