如何在使用spring和@Transaction的同时将全局变量从一个类发送到另一类?

时间:2019-02-23 06:42:57

标签: java spring-boot spring-mvc spring-data-jpa spring-transactions

我正在尝试制定一个示例Spring Boot(MVC)项目,在其中我尝试以相同的顺序执行以下操作。

  1. 添加一个客户
  2. 添加具有客户ID的联系人
  3. 添加同时具有客户和联系人ID的Oppr
  4. 发送电子邮件给联系人
  5. 添加具有opprId的票证

这里的主要问题是我正在尝试完成一项交易下的所有任务。但是添加票证的方法在另一个类中。在尝试添加票证时,我需要将opprId发送到TicketAdd类。我可以在方法级别不使用@Transaction时获取全局变量值,但此刻我在AddTicket类中将@Transaction用于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 Service类。在该类中,如果我使用@Transactional,则无法获得我在OpprAdd类中设置的ticketOwner和ticketOpprId值。

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 :(得分:0)

代替

  

@Transactional(传播=传播。REQUIRES_NEW)

尝试

  

@Transactional(propagation = Propagation.SUPPORTS)

说明:

REQUIRES_NEW:

表示每次调用目标方法时必须开始新的发送。如果已经在进行发送,则在开始新的发送之前将其暂停。

支持:

表示无论atx如何均可执行目标方法。如果atxis运行,它将参与相同的TX。如果执行时没有发送TX,即使没有错误,它仍然会执行。 提取数据的方法是此选项的最佳选择。

答案 1 :(得分:0)

从下面的代码中可以看到:

        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);
    }

我希望它能起作用。