오류 사항
한가지 문제가 생겼었습니다.
ajax 자체를 함수를 읽어오지 못하는 오류가 있어서 인터넷 서칭을 해서 오류를 해결했습니다.

slim 제이쿼리는 ajax 사용을 방지하는 코드가 있어 ajax를 사용할 수가 없어서 이 문구를 지우고 대신

제이쿼리를 불러와 사용하여 오류를 해결하였습니다.
JPA 설정을 초기화 하고 싶다면

AJAX 요청
package com.junho.blog.dto;
import org.springframework.http.HttpStatus;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class ResponseDto<T> {
int status;
T data;
}
=================== AJAX ===================
$.ajax({
type: "POST",
url: "/blog/api/user",
data: JSON.stringify(data), // HTTP body 데이터
// contentType: "application/json; charset=utf-8", // body 데이터가 어떤 타입인지(MIME)
dataType: "json", // 요청을 서버로해서 응답이 왔을 때 json이라면 javascript 타입으로 변경시켜줍니다.
success: function(response) {
alert("회원가입이 완료되었습니다.");
console.log(response);
// location.href = "/blog";
},
error: function(xhr, status, error) {
alert("오류가 발생하였습니다. 상태 코드: " + xhr.status);
console.error("에러: ", error);
}
});
=================== Controller ===================
@PostMapping("/api/user")
public ResponseDto<Integer> join(@RequestBody User user) {
log.info("Join User {}", user);
int result = userService.join(user);
return new ResponseDto<Integer>(HttpStatus.OK.value(), result);
}
=================== Service ===================
@Transactional
public int join(User user) {
try {
user.setRole(RoleType.USER);
log.debug("userRepository : join 회원가입 User Info{}"+ user);
userRepository.save(user);
return 1;
} catch (Exception e) {
e.printStackTrace();
log.debug("userRepository : join 회원가입 오류 메세지{}"+ e.getMessage());
}
return -1;
}
=================== GlobalExceptionHandler ===================
@ExceptionHandler(value=Exception.class)
public ResponseDto<String> handleArgumentException(Exception e) {
return new ResponseDto<String>(HttpStatus.OK.value(), e.getMessage());
}
// 예외처리 헨들러도 변경시켜줍니다.

트렌잭션

DB read commit - 트렌잭션을 시작으로 commit이 되기 전 데이터를 보여주고 commit 후에 온전히 바뀐 데이터를 확인 할 수 있다. 하지만 여기서 문제가 발생 할 수 있다
두 이용자가 1T, 2T 다른 트렌잭션 시작했다고 가정하자.
그러면 2T가 값을 가져오는 도중 1T가 값을 변경 시켜 2T에는 예상한 값과 다른 값이 나오는 데이터 오류가 생긴다 따라서 이걸 해결하기 위해
REPEACTABLE READ 를 활용하는데, 2T가 실행하는 동안에는 그 전에 끝난 트렌잭션에 값에 영향만 받고 같은 시간에 실행하는 트렌잭션에는 데이터 영향을 없애는 방식이다.

스프링부트 트렌잭션
세션의 시작은 서블릿이 시작되는 시점부터 ~ (영속성 컨텍스트를 포함)
트렌잭션의 시작은 서비스 레이어부터, JDBC 커넥션도 이 시점부터,
트렌잭션의 종료는 서비스 계층에서 종료, JDBC 커넥션도 이 시점부터 종료.
세션의 컨트롤러 영역까지 끌고 가기 때문에 영속성이 보장되어 select가 가능해지고 lazy-loding이 가능해진다.
lazy 전략은 영속성 컨텍스트에 외래키에 묶여있는 객체 정보를 프록시로 저장해두었다가 컨트롤러에서 다시 팀 정보를 불러올 수 있습니다.