java - 如何在使用spring和@Transaction时将全局变量从一个类发送到另一个类?
问题描述
我正在尝试制定一个示例 Spring Boot(MVC) 项目,我正在尝试以相同的顺序执行以下操作。
- 添加一位客户
- 添加具有客户 ID 的联系人
- 添加具有客户和联系人 ID 的 Oppr
- 向联系人发送电子邮件
- 添加具有 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);
}
}
解决方案
代替
@Transactional(传播=传播.REQUIRES_NEW)
尝试
@Transactional(传播=传播.支持)
解释:
REQUIRES_NEW:
表示每次调用目标方法时都必须启动一个新的 tx。如果已经有一笔交易正在进行,它将在开始新的交易之前暂停。
支持:
表示目标方法可以执行,而与 atx 无关。如果 atxis 运行,它将参与相同的 tx。如果在没有 tx 的情况下执行,如果没有错误,它仍然会执行。获取数据的方法是此选项的最佳候选者。
推荐阅读
- php - bind_param 不会替换我准备好的语句中的 ?s
- python - 如何在窗口底部放置一个画布对象?
- python - 为什么在python中解析xml文件会在文件中有“/>”的地方添加空格?
- javascript - 使用 jquery 或 javascript 进行图像滑动垂直滚动
- docker - Windows docker 容器中的 selenium 因 ff/chrome “会话因页面崩溃而被删除”而失败
- node.js - 错误 [ERR_STREAM_PREMATURE_CLOSE]:节点管道流中过早关闭
- flutter - Flutter:列出设备上存储的所有图像
- html - HTML:视频背景块徽标
- flutter - 带有 Flutter_Map 的简单 Flutter 应用程序不起作用
- ios - Swift & Firebase - 数据库和用户默认值