Как отправить глобальную переменную из одного класса в другой при использовании Spring и @Transaction? - PullRequest
0 голосов
/ 23 февраля 2019

Я пытаюсь разработать пример проекта Spring Boot (MVC), в котором я пытаюсь выполнить следующее в той же последовательности.

  1. добавить одного клиента
  2. добавитьдля контакта с идентификатором клиента
  3. добавьте Oppr с идентификатором клиента и контакта
  4. отправьте электронное письмо контактному лицу
  5. добавьте билет с opprId

Основная проблема здесь заключается в том, что я пытаюсь выполнить все задачи в рамках одной транзакции.Но метод добавления билета находится в другом классе.При попытке добавить билет мне нужно отправить opprId в класс TicketAdd.Я могу получить значение глобальной переменной, пока я не использую @Transaction на уровне метода, но в данный момент я использую @Transaction в классе AddTicket для метода addFields, а затем не могу получить значение глобальной переменной.

Это мой класс сервиса OpprAdd.

package com.transaction.spring.service;

import java.util.Date;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.web.servlet.ModelAndView;

import com.transaction.spring.model.Customer;
import com.transaction.spring.model.CustomerContact;
import com.transaction.spring.model.SalesOppr;
import com.transaction.spring.repo.ContactRepo;
import com.transaction.spring.repo.CustomerRepo;
import com.transaction.spring.repo.OpprRepo;

@Service
public class OpprAdd {
    @Autowired
    ContactRepo contactRepo;

    @Autowired
    CustomerRepo customerRepo;

    @Autowired
    OpprRepo opprRepo;

    @Autowired
    TicketAdd ticketAdd;

    public ModelAndView getModelAndView(Model model, ModelAndView modelAndView) {
        modelAndView.addObject("SalesOppr", new SalesOppr());
        modelAndView.setViewName("enquiry-add");
        return modelAndView;

    }

    public ModelAndView postModelAndView(Model model, SalesOppr SalesOppr, ModelAndView modelAndView) {

        addOppr(SalesOppr);

        modelAndView.addObject("SalesOppr", SalesOppr);
        modelAndView.setViewName("enquiry-add");
        return modelAndView;
    }

    private void sendEmailSms(SalesOppr SalesOppr) {
        System.err.println("123");
    }

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void addOppr(SalesOppr SalesOppr) {
        Customer Customer = new Customer();
        Customer.setCustomerName(SalesOppr.getCustomerName());

        customerRepo.save(Customer);

        CustomerContact CustomerContact = new CustomerContact();
        CustomerContact.setContactFname(SalesOppr.getContactFname());
        CustomerContact.setContactLname(SalesOppr.getContactLname());
        CustomerContact.setContactCustomerId(Customer.getCustomerId());

        contactRepo.save(CustomerContact);

        SalesOppr.setOpprTitle("New Oppr");
        SalesOppr.setOpprDate(new Date());
        SalesOppr.setOpprDesc("Hello");
        SalesOppr.setOpprCustomerId(Customer.getCustomerId());
        SalesOppr.setOpprContactId(CustomerContact.getContactId());
        opprRepo.save(SalesOppr);

        sendEmailSms(SalesOppr);

        ticketAdd.ticketOwner = "1";
        ticketAdd.ticketOpprId = String.valueOf(SalesOppr.getOpprId());
        ticketAdd.addFields();

    }

}

Это мой класс сервиса TicketAdd. В этом классе, если я использую @Transactional, я не получаю значения ticketOwner и ticketOpprId, которые я установил в классе OpprAdd.

package com.transaction.spring.service;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class TicketAdd {

    public String ticketOwner = "0";
    public String ticketOpprId = "0";

    @Transactional
    public void addFields() {
        System.out.println("ticketOwner====" + ticketOwner);
        System.out.println("ticketOpprId====" + ticketOpprId);
    }
}

Ответы [ 2 ]

0 голосов
/ 25 февраля 2019

Как видно из приведенного ниже кода:

        ticketAdd.ticketOwner = "1";
        ticketAdd.ticketOpprId = String.valueOf(SalesOppr.getOpprId());
        ticketAdd.addFields();

То, что изменения, внесенные в ticketAdd, не сохраняются / не фиксируются.

Итак, когда вы читаете значение в другом классе, оно не восстанавливается из-за природы по умолчанию @Transactional.Итак, попробуйте следующее:

    @Transactional(isolation=Isolation.READ_UNCOMMITTED)
    public void addFields() {
        System.out.println("ticketOwner====" + ticketOwner);
        System.out.println("ticketOpprId====" + ticketOpprId);
    }

Я надеюсь, что это работает.

0 голосов
/ 23 февраля 2019

Вместо

@ Транзакционный (распространение = Propagation.REQUIRES_NEW)

Попробуйте

@ Транзакционный (распространение = Propagation.SUPPORTS)

Объяснение:

REQUIRES_NEW:

Указывает, что новый tx должен запускаться каждый раз, когда вызывается целевой метод.Если передача уже выполняется, она будет приостановлена ​​перед началом новой.

ПОДДЕРЖКА:

Указывает, что целевой метод может выполняться независимо от atx.Если Atxis работает, он будет участвовать в той же передаче.Если выполняется без передачи, он все равно будет выполняться, если ошибок нет.Методы, которые выбирают данные, являются наилучшими кандидатами для этой опции.

...