Java 关于创建事务的控制器方法问题
大家好 我有以下几种情况 两个表-账户和交易 想法很简单——在两个账户之间创建交易时,唯一的问题是只涉及两个账户Java 关于创建事务的控制器方法问题,java,spring,hibernate,h2,Java,Spring,Hibernate,H2,大家好 我有以下几种情况 两个表-账户和交易 想法很简单——在两个账户之间创建交易时,唯一的问题是只涉及两个账户 - sender new balance = senderAccountBalance - transactionAmount - receiver new balance = receiverAccountBalance + transactionAmount 我正在扩展JpaRepositories 执行@PostMapping/transactions方法不会更改Sende
- sender new balance = senderAccountBalance - transactionAmount
- receiver new balance = receiverAccountBalance + transactionAmount
我正在扩展JpaRepositories
执行@PostMapping/transactions方法不会更改SenderAccount余额属性或ReceiverAccount余额属性-以下是控制器方法和实体的代码
我需要修复此选项或找到另一个选项,因为我现在有点卡住了:{
@PostMapping("/transactions")
public ResponseEntity<Transaction> createTransaction(@Valid @RequestBody Transaction transaction) {
final Transaction result = transactionRepository.save(transaction);
final URI location = ServletUriComponentsBuilder.fromCurrentRequest().
path("/{id}")
.buildAndExpand(result.getId()).toUri();
Integer emitterBalance = accountRepository.findById(transaction.getSenderAccountId()).get().getBalance();
Integer receptorBalance = accountRepository.findById(transaction.getReceiverAccountId()).get().getBalance();
Integer amount = transactionRepository.findById(transaction.getId()).get().getAmount();
Integer emitterFinalBalance = emitterBalance - amount;
Integer receptorFinalBalance = receptorBalance + amount;
accountRepository.findById(transaction.getSenderAccountId()).get().setBalance(emitterFinalBalance);
accountRepository.findById(transaction.getReceiverAccountId()).get().setBalance(receptorFinalBalance);
return ResponseEntity.created(location).build();
}
你能帮我解决这个问题吗?
感谢您的支持!:只需将您的方法标记为@Transactional即可
否则,存储库将返回处于分离状态的实体。修改不会被跟踪,要保存修改,必须通过调用repository.saveentity显式保存它们。如下所示:
@PostMapping("/transactions")
public ResponseEntity<Transaction> createTransaction(@Valid @RequestBody Transaction transaction) {
...
var senderAccount = accountRepository.findById(transaction.getSenderAccountId()).get();
senderAccount.setBalance(emitterFinalBalance);
accountRepository.save(senderAccount);
var receiverAccount = accountRepository.findById(transaction.getReceiverAccountId()).get();
receiverAccount.setBalance(receptorFinalBalance);
accountRepository.save(receiverAccount);
return ResponseEntity.created(location).build();
}
你的方法需要是事务性的。否则你只会修改分离的对象。请使用变量,不要调用Optional.get,并了解实体之间的关联:事务不应该有帐户ID。它应该有帐户本身。嘿,Max,谢谢你的回复,但我对这部分不太了解关于显式调用repository.saveentity-您能帮我修复代码的一部分来澄清这一点吗?@PavelS我已经用示例更新了答案,请看一看。请记住,只有@Transactional方法在单个事务中完成。如果方法不是事务性的,则每个DB操作都会保存一次在单独的事务中完成。
public class Transaction {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotNull
private Integer amount;
@NotNull
private Instant created;
@NotNull
private Long senderAccountId;
@NotNull
private Long receiverAccountId;
@JsonIgnore
@ManyToOne
@JoinColumn(name = "emitterId")
private Account emitterId;
@JsonIgnore
@ManyToOne
@JoinColumn(name = "receptorId")
private Account receptorId;
public Transaction(Long id,Integer amount, Account emitterId, Account receptorId){
this.created = Instant.now();
this.amount = amount;
this.emitterId = emitterId;
this.receptorId = receptorId;
this.id = id;
senderAccountId = this.emitterId.getId();
receiverAccountId = this.receptorId.getId();
}
}
@PostMapping("/transactions")
public ResponseEntity<Transaction> createTransaction(@Valid @RequestBody Transaction transaction) {
...
var senderAccount = accountRepository.findById(transaction.getSenderAccountId()).get();
senderAccount.setBalance(emitterFinalBalance);
accountRepository.save(senderAccount);
var receiverAccount = accountRepository.findById(transaction.getReceiverAccountId()).get();
receiverAccount.setBalance(receptorFinalBalance);
accountRepository.save(receiverAccount);
return ResponseEntity.created(location).build();
}
@PostMapping("/transactions")
@Transactional
public ResponseEntity<Transaction> createTransaction(@Valid @RequestBody Transaction transaction) {
...