首页 > 解决方案 > 如何在使用spring和@Transaction时将全局变量从一个类发送到另一个类?

问题描述

我正在尝试制定一个示例 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 服务类。在这个类中,如果我使用 @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);
    }
}

标签: javaspring-bootspring-mvcspring-data-jpaspring-transactions

解决方案


代替

@Transactional(传播=传播.REQUIRES_NEW)

尝试

@Transactional(传播=传播.支持)

解释:

REQUIRES_NEW:

表示每次调用目标方法时都必须启动一个新的 tx。如果已经有一笔交易正在进行,它将在开始新的交易之前暂停。

支持:

表示目标方法可以执行,而与 atx 无关。如果 atxis 运行,它将参与相同的 tx。如果在没有 tx 的情况下执行,如果没有错误,它仍然会执行。获取数据的方法是此选项的最佳候选者。


推荐阅读