在一个service调用另一个service会是在同一个事务吗

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在一个service调用另一个service会是在同一个事务吗相关的知识,希望对你有一定的参考价值。

参考技术A 不是同一个事务。
service层如果使用事务的话,是不能相互嵌套的。即serviceA的方法a如果使用事务,serviceB的方法b也使用事务,在serviceA的a方法里调serviceB的b方法.
可以把b的方法体拷出来,直接放到a里

使用 Spring Boot 从另一个服务调用 Rest Service 以进行课程注册系统

【中文标题】使用 Spring Boot 从另一个服务调用 Rest Service 以进行课程注册系统【英文标题】:Calling a Rest Service from another service for course registration system with spring boot 【发布时间】:2020-01-24 20:16:25 【问题描述】:

我试图通过我的 Registration 微服务进行 REST 调用(学生,课程微服务) 插入新注册的服务,但每当我调用这些服务时,Student 微服务都会显示以下错误

> org.springframework.web.client.RestClientException: Error while extracting response for type [class com.homeexam.registrationmanagementserver.model.Student] and content type [application/json;charset=UTF-8]; nested exception is org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize instance of `com.homeexam.registrationmanagementserver.model.Student` out of START_ARRAY token; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `com.homeexam.registrationmanagementserver.model.Student` out of START_ARRAY token
 at [Source: (PushbackInputStream); line: 1, column: 1]

我已尽力解决从谷歌搜索的问题,但我找不到任何与该问题相关的解决方案。救命,我出去!

这是我的 RegistrationService 类,我在其中调用这些微服务:

    public Registration create(Registration registration) 

            Student student = restTemplate.getForObject(studentsUrl, Student.class);
            Section section = restTemplate.getForObject(sectionsUrl, Section.class);
            Course course = restTemplate.getForObject(coursesUrl, Course.class);


            /*registration = new Registration(registration.getId(), student.getId(),student.getProgram(),
                    section.getSectionNumber(),course.getCourseCode(),section.getFacultyInitial());*/
            registration.setId(registration.getId());
            registration.setStudentId(student.getId());
            registration.setProgramName(student.getProgram());
            registration.setCourseCode(course.getCourseCode());
            registration.setFacultyInitial(section.getFacultyInitial());
            registration.setSectionNumber(section.getSectionNumber());

            Optional<Registration> optionalReg = registrationRepository.findById(registration.getId());
            Optional<Registration> byCourseCode = registrationRepository.findById(Integer.valueOf(registration.getCourseCode()));
            if (optionalReg.isPresent() ) 
                throw new ResourceAlreadyExistsException();
             else if (byCourseCode.isPresent())
               throw new AlreadyRegisteredException();
            else 
               return registrationRepository.save(registration);
            
        

但是,代码确实可以在不调用微服务相关信息的情况下工作。

注册 JSON


  "courseCode": "string",
  "facultyInitial": "string",
  "id": 0,
  "programName": "string",
  "sectionNumber": 0,
  "studentId": "string"

学生 JSON


    "id": "201600000001",
    "name": "UML Diagram",
    "email": "uml@gmail.com",
    "address": "Texas,USA",
    "dob": "1998-09-11",
    "mobileNumber": "01110000000",
    "dateOfAdmission": "2018-09-10",
    "program": "BSc. in EEE",
    "role": "Student",
    "password": "1555"
  

课程 JSON

[
  
    "courseCode": "CS193",
    "courseTitle": "Android Application",
    "courseCredit": 3,
    "sectionList": [
      
        "id": 1,
        "sectionNumber": 1,
        "seatLimit": 25,
        "semesterNumber": 11,
        "facultyInitial": "ATA",
        "course": 
          "courseCode": "CS193",
          "courseTitle": "Android Application",
          "courseCredit": 3,
          "sectionList": null,
          "gradeList": null
        
      ,
      
        "id": 2,
        "sectionNumber": 2,
        "seatLimit": 30,
        "semesterNumber": 11,
        "facultyInitial": "ABA",
        "course": 
          "courseCode": "CS193",
          "courseTitle": "Android Application",
          "courseCredit": 3,
          "sectionList": null,
          "gradeList": null
        
      
    ],
    "gradeList": null
  
]

部分 JSON

[
  
    "id": 1,
    "sectionNumber": 1,
    "seatLimit": 25,
    "semesterNumber": 11,
    "facultyInitial": "ATA",
    "course": 
      "courseCode": "CS193",
      "courseTitle": "Android Application",
      "courseCredit": 3,
      "sectionList": null,
      "gradeList": null
    
  ,
  
    "id": 2,
    "sectionNumber": 2,
    "seatLimit": 30,
    "semesterNumber": 11,
    "facultyInitial": "ABA",
    "course": 
      "courseCode": "CS193",
      "courseTitle": "Android Application",
      "courseCredit": 3,
      "sectionList": null,
      "gradeList": null
    
  
]

Student.java

@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(of = "id","name")
@Document
public class Student 
    @Id
    private String id;
    private String name;
    private String email;
    private String address;
    private LocalDate dob;
    private String mobileNumber;
    private LocalDate dateOfAdmission;
    private String program;
    private Role role;
    private String password;

Registration.java

public class Registration 
    @Id
    private int id;
    private String studentId;
    private String programName;
    private int sectionNumber;
    private String courseCode;
    private String facultyInitial;

【问题讨论】:

错误消息与格式错误的 JSON 有关。能否将 json 内容添加到问题中? @henriqueor 我添加了 JSON 数据 你能不能把Student.java sahre一下 @deshi 以下链接包含 Student.java 类Student.java 始终将代码添加到问题中而不是外部链接上,以保留历史记录以供将来参考。 @JakariaRidoy 【参考方案1】:

错误意味着您向需要单个对象的服务发送了一个数组。

解决方案:为每个请求发送单个 JSON 对象或更改服务以使其接受数组或列表。

【讨论】:

我应该更改哪个服务层 StudentServiceRegistrationService StudentService.java 每当我调用这些服务时 - 它与其他服务有什么关系?首先分析您对 Student 负责的服务。从您的首选客户端(Postman、curlt、...)调用 GET,检查结构。调用 POST 和 PUT,检查它们是否正常工作。 (学生和课程)服务都可以正常工作。他们可以执行所有 CRUD 操作。【参考方案2】:

试试这个:

Student[] students = restTemplate.getForObject(studentsUrl, Student[].class);

【讨论】:

【参考方案3】:

问题可能出在 Student 的角色属性上。在您的 Student 类上,它期望接收 Role 类型,但在您的 JSON 中它是一个 String。

你有这个:


    "id": "201600000001",
    "name": "UML Diagram",
    "email": "uml@gmail.com",
    "address": "Texas,USA",
    "dob": "1998-09-11",
    "mobileNumber": "01110000000",
    "dateOfAdmission": "2018-09-10",
    "program": "BSc. in EEE",
    "role": "Student",
    "password": "1555"

但应该是这样的:


    "id": "201600000001",
    "name": "UML Diagram",
    "email": "uml@gmail.com",
    "address": "Texas,USA",
    "dob": "1998-09-11",
    "mobileNumber": "01110000000",
    "dateOfAdmission": "2018-09-10",
    "program": "BSc. in EEE",
    "role": 
        "type": "Student"
    ,
    "password": "1555"

由于不知道Role类的结构,所以以设置属性“type”为例。

【讨论】:

以上是关于在一个service调用另一个service会是在同一个事务吗的主要内容,如果未能解决你的问题,请参考以下文章

Angular Service 在每次调用时都会重置

使用 Spring Boot 从另一个服务调用 Rest Service 以进行课程注册系统

如何从 Vuex/Vuejs 中的动作中调用另一个动作?

Spring中同一个service中方法相互调用事务不生效问题解决方案

写一个servlet如果不重写service方法那么会调用哪个类的service方法来调用doGet/doPost

SpringMVC+SpringBoot+MyBatis