mirror of
https://github.com/Example-uPagge/transactional.git
synced 2024-06-14 11:52:55 +03:00
spring transaction example
This commit is contained in:
parent
cbe943be85
commit
8e259a6a4e
57
spring-transaction/pom.xml
Normal file
57
spring-transaction/pom.xml
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<parent>
|
||||||
|
<artifactId>spring-boot-transaction</artifactId>
|
||||||
|
<groupId>dev.struchkov.example</groupId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>spring-transaction</artifactId>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>17</maven.compiler.source>
|
||||||
|
<maven.compiler.target>17</maven.compiler.target>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencyManagement>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-dependencies</artifactId>
|
||||||
|
<version>2.7.2</version>
|
||||||
|
<type>pom</type>
|
||||||
|
<scope>import</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</dependencyManagement>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- <dependency>-->
|
||||||
|
<!-- <groupId>jakarta.persistence</groupId>-->
|
||||||
|
<!-- <artifactId>jakarta.persistence-api</artifactId>-->
|
||||||
|
<!-- <version>3.1.0</version>-->
|
||||||
|
<!-- </dependency>-->
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
11
spring-transaction/rest/person-requests.http
Normal file
11
spring-transaction/rest/person-requests.http
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
### Смотрим на первого пользователя
|
||||||
|
GET http://localhost:8080/api/person/1
|
||||||
|
Accept: application/json
|
||||||
|
|
||||||
|
### Смотрим на второго пользователя
|
||||||
|
GET http://localhost:8080/api/person/2
|
||||||
|
Accept: application/json
|
||||||
|
|
||||||
|
### Смотрим на третьего пользователя
|
||||||
|
GET http://localhost:8080/api/person/3
|
||||||
|
Accept: application/json
|
9
spring-transaction/rest/transaction-money-requests.http
Normal file
9
spring-transaction/rest/transaction-money-requests.http
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
### Отправляем деньги от первого пользователя втором
|
||||||
|
POST http://localhost:8080/api/money/send
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"personFrom": 1,
|
||||||
|
"personTo": 2,
|
||||||
|
"amount": 100
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
package dev.struchkov.example.transaction;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
public class Application {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(Application.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
package dev.struchkov.example.transaction.controller;
|
||||||
|
|
||||||
|
import dev.struchkov.example.transaction.domain.Person;
|
||||||
|
import dev.struchkov.example.transaction.repository.PersonRepository;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/person")
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class PersonController {
|
||||||
|
|
||||||
|
private final PersonRepository personRepository;
|
||||||
|
|
||||||
|
@GetMapping("{id}")
|
||||||
|
public Optional<Person> getById(@PathVariable Long id) {
|
||||||
|
return personRepository.findById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
package dev.struchkov.example.transaction.controller;
|
||||||
|
|
||||||
|
import dev.struchkov.example.transaction.dto.TransactionDto;
|
||||||
|
import dev.struchkov.example.transaction.service.TransactionMoneyService;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("api/money")
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class TransactionMoneyController {
|
||||||
|
|
||||||
|
private final TransactionMoneyService service;
|
||||||
|
|
||||||
|
@PostMapping("send")
|
||||||
|
public HttpStatus sendMoney(@RequestBody TransactionDto transactionDto) {
|
||||||
|
service.sendMoney(
|
||||||
|
transactionDto.getPersonFrom(),
|
||||||
|
transactionDto.getPersonTo(),
|
||||||
|
transactionDto.getAmount()
|
||||||
|
);
|
||||||
|
return HttpStatus.OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
package dev.struchkov.example.transaction.domain;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.GenerationType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@Table(name = "person")
|
||||||
|
public class Person {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Column(name = "name")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Column(name = "balance")
|
||||||
|
private Long balance;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
package dev.struchkov.example.transaction.domain;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.GenerationType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.JoinColumn;
|
||||||
|
import javax.persistence.ManyToOne;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@Table(name = "transaction")
|
||||||
|
public class TransactionMoney {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
@JoinColumn(name = "person_from")
|
||||||
|
private Person personFrom;
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
@JoinColumn(name = "person_to")
|
||||||
|
private Person personTo;
|
||||||
|
|
||||||
|
@Column(name = "amount")
|
||||||
|
private Long amount;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
package dev.struchkov.example.transaction.dto;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class TransactionDto {
|
||||||
|
|
||||||
|
private Long personFrom;
|
||||||
|
private Long personTo;
|
||||||
|
private Long amount;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
package dev.struchkov.example.transaction.repository;
|
||||||
|
|
||||||
|
import dev.struchkov.example.transaction.domain.Person;
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import org.springframework.data.jpa.repository.Query;
|
||||||
|
import org.springframework.data.repository.query.Param;
|
||||||
|
|
||||||
|
public interface PersonRepository extends JpaRepository<Person, Long> {
|
||||||
|
|
||||||
|
@Query(nativeQuery = true, value = "SELECT person.balance FROM person WHERE id = :id")
|
||||||
|
Long getBalance(@Param("id") Long id);
|
||||||
|
|
||||||
|
@Query("SELECT p.balance FROM Person p WHERE p.id = :id")
|
||||||
|
Long getBalanceJpql(@Param("id") Long id);
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package dev.struchkov.example.transaction.repository;
|
||||||
|
|
||||||
|
import dev.struchkov.example.transaction.domain.TransactionMoney;
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
|
||||||
|
public interface TransactionMoneyRepository extends JpaRepository<TransactionMoney, Long> {
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
package dev.struchkov.example.transaction.service;
|
||||||
|
|
||||||
|
import dev.struchkov.example.transaction.domain.Person;
|
||||||
|
import dev.struchkov.example.transaction.domain.TransactionMoney;
|
||||||
|
import dev.struchkov.example.transaction.repository.PersonRepository;
|
||||||
|
import dev.struchkov.example.transaction.repository.TransactionMoneyRepository;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class TransactionMoneyService {
|
||||||
|
|
||||||
|
private final TransactionMoneyRepository transactionMoneyRepository;
|
||||||
|
private final PersonRepository personRepository;
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public void sendMoney(@NonNull Long personFromId, @NonNull Long personToId, @NonNull Long amount) {
|
||||||
|
final Person personFrom = personRepository.findById(personFromId).orElseThrow();
|
||||||
|
final Person personTo = personRepository.findById(personToId).orElseThrow();
|
||||||
|
|
||||||
|
final TransactionMoney transactionMoney = new TransactionMoney();
|
||||||
|
transactionMoney.setPersonTo(personTo);
|
||||||
|
transactionMoney.setPersonFrom(personFrom);
|
||||||
|
transactionMoney.setAmount(amount);
|
||||||
|
|
||||||
|
transactionMoneyRepository.save(transactionMoney);
|
||||||
|
personFrom.setBalance(personFrom.getBalance() - amount);
|
||||||
|
personTo.setBalance(personTo.getBalance() + amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void surprise() {
|
||||||
|
throw new RuntimeException("Сюрприиииз");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
15
spring-transaction/src/main/resources/application.yml
Normal file
15
spring-transaction/src/main/resources/application.yml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
spring:
|
||||||
|
datasource:
|
||||||
|
password: 121314Ma
|
||||||
|
username: postgres
|
||||||
|
url: jdbc:postgresql://localhost:5432/test
|
||||||
|
driver-class-name: org.postgresql.Driver
|
||||||
|
|
||||||
|
jpa:
|
||||||
|
properties:
|
||||||
|
hibernate:
|
||||||
|
format_sql: true
|
||||||
|
logging:
|
||||||
|
level:
|
||||||
|
org.springframework.orm.jpa: DEBUG
|
||||||
|
org.springframework.transaction: DEBUG
|
14
spring-transaction/src/main/resources/logback.xml
Normal file
14
spring-transaction/src/main/resources/logback.xml
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<configuration>
|
||||||
|
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||||
|
<encoder>
|
||||||
|
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<logger name="org.hibernate.SQL" level="DEBUG" />
|
||||||
|
<logger name="org.hibernate.type" level="TRACE" />
|
||||||
|
|
||||||
|
<root level="info">
|
||||||
|
<appender-ref ref="STDOUT"/>
|
||||||
|
</root>
|
||||||
|
</configuration>
|
Loading…
x
Reference in New Issue
Block a user