我正在尝试创建一个用于转账的 API
即取款和存款。
我使用@Transactional Annotation 执行事务。
但有一些标准,即如果银行帐号不存在,则应通过运行时异常。
我将附上其中的代码。现在,当调用 TransferBalanceMethod 时,如果存款人银行账户不存在,则提取的金额也应该回滚。
但这并没有发生。是指当A账户向B账户转账1000卢比时,如果B账户的存款出现异常,则A账户的提款也应该被提取。
我也尝试了 @Transactional 注释以及 Exception 类的 rollbackFor 属性
我也尝试为存款和取款方法添加 @Transaction 注释,但我们使用相同的交易,因为我们使用传播必需**
Model Class//This is the Model Class
//All Imports
@Entity
public class BankAccount {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
private Integer id;
@Column(name = "bankAccountNumber", nullable = false,unique = true)
@NotNull
@Size(min = 5, message = "Bank account number should be greater than 5 characters")
private String bankAccountNumber;
@NotNull
@Column(name = "balance", nullable = false)
@Min(1000)
private Long balance;
//Getter Setter and Constructor
**Controller File**//This is the Controller Class
//All imports and other stuff such as @RestController, @Autowired
@GetMapping("/bankaccount/transfer")
public void transferBalance(@RequestParam("bankAccountNo1") String bankAccountNo1, @RequestParam("bankAccountNo2") String bankAccountNo2,
@RequestParam("balance") Long balance) throws RuntimeException
{
bankService.transferBalance(bankAccountNo1,bankAccountNo2, balance);
}
}
**Service File:-**//This is Service Layer
//All imports
@Service
public class BankService {
@Autowired
private BankRepository bankRepository;
@Autowired
private ModelMapper modelMapper;
public List<BankAccountDTO> getAllBankAccount() {
List<BankAccountDTO> bankAccountDTO = new ArrayList<BankAccountDTO>();
List<BankAccount> bankAccount = bankRepository.findAll();
for (BankAccount b : bankAccount) {
bankAccountDTO.add(modelMapper.map(b, BankAccountDTO.class));
}
return bankAccountDTO;
}
public ResponseEntity<?> getIndividualBankAccount(String bankAccountNumber) {
BankAccount bankAccount = bankRepository.findByBankAccountNumber(bankAccountNumber);
if (bankAccount == null) {
return new ResponseEntity<>("Account not found", HttpStatus.BAD_REQUEST);
} else {
return new ResponseEntity<>(
modelMapper.map(bankRepository.findByBankAccountNumber(bankAccountNumber), BankAccountDTO.class),
HttpStatus.OK);
}
}
public Object addBankAccount(BankAccountDTO bankAccountDTO) {
return bankRepository.save(modelMapper.map(bankAccountDTO, BankAccount.class));
}
@Transactional(propagation = Propagation.REQUIRED)
public void depositBalance(String bankAccountNumber, Long balance) throws RuntimeException {
BankAccount bankAccNo = bankRepository.findByBankAccountNumber(bankAccountNumber);
if (bankAccNo == null) {
throw new RuntimeException("Bank Accout Number is not found : " + bankAccountNumber);
} else {
if (balance <= 0) {
throw new RuntimeException("Please deposit appropriate balance");
} else {
Long amount = bankAccNo.getBalance() + balance;
bankAccNo.setBalance(amount);
bankRepository.save(bankAccNo);
}
}
}
@Transactional(propagation = Propagation.REQUIRED)
public void withdrawBalance(String bankAccountNumber, Long balance) throws RuntimeException {
BankAccount bankAccNo = bankRepository.findByBankAccountNumber(bankAccountNumber);
if (bankAccNo == null) {
throw new RuntimeException("Bank Account not found :" + bankAccountNumber);
} else {
if (balance <= 0) {
throw new RuntimeException("Please withdraw appropriate balance");
} else {
Long amount = bankAccNo.getBalance() - balance;
if (amount < 1000) {
throw new RuntimeException("Sorry Cannot withdraw.Your minimum balance should be thousand rupees!");
} else {
bankAccNo.setBalance(amount);
bankRepository.save(bankAccNo);
}
}
}
}
@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = RuntimeException.class)
public void transferBalance(String bankAccountNo1, String bankAccountNo2, Long balance) throws RuntimeException {
try {
withdrawBalance(bankAccountNo1, balance);
depositBalance(bankAccountNo2, balance);
} catch (RuntimeException e) {
throw e;
}
}
}