在一个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 对象或更改服务以使其接受数组或列表。
【讨论】:
我应该更改哪个服务层 StudentService 或 RegistrationService 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会是在同一个事务吗的主要内容,如果未能解决你的问题,请参考以下文章
使用 Spring Boot 从另一个服务调用 Rest Service 以进行课程注册系统
Spring中同一个service中方法相互调用事务不生效问题解决方案