Нет, к сожалению, аннотация spring @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, но обычно в транзакциях, управляемых контейнером (например, JBoss, WebLogic и т. д.); это будет подход.
В качестве дополнительной панели, если вы уже на весеннем пути, я могу предложить вам проверить spring-batch
. Он обеспечивает достойную основу для пакетных операций для множества вариантов использования. То, что я описал выше, представляет собой грубую реализацию одного случая внутри spring-batch
.
ОБНОВЛЕНИЕ
Если вы хотите избежать необходимости создавать несколько реализаций классов сегментов с подробностями аннотаций, вы можете прибегнуть к конфигурации XML и иметь реализацию одного класса:
<bean id="shard1" class="default.ShardStudentServiceImpl">
<property name="entityManager" ref="shard1EntityManager" />
<property name="transactionManager" ref="shard1TransactionManager" />
</bean>
Единственная разница здесь в том, что вы должны определить свои 25 осколков в XML, а затем вам нужно написать свой собственный код для запуска, фиксации и управления транзакцией внутри вашего класса ShardStudentServiceImpl
.
Используя абстрактный базовый класс в сочетании с аннотациями в окончательных реализациях, показанных выше, мое обновление достигает того же места назначения. На самом деле, если вы посмотрите на spring-batch
, вы заметите, что их пакетная конфигурация следует аналогичной предпосылке с указанием менеджера сущностей и менеджеров транзакций в качестве входных свойств для одного класса.
person
Naros
schedule
11.12.2015