Создаю n независимых потоков, после выполнения метода transaction должно происходить изменение значений (c одного счета должны уходить деньги на другой), но после выполнения, значения не изменяются. По умолчанию в методе save добавляю на каждый счет 10000. Должно произойти 9 транзакций и после этого программа должна завершится.
@Entity
@Table
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class Account {
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.AUTO)
@Getter
private long id;
@Column(name= "money")
@Getter
@Setter
private int money;
public static AtomicInteger numberTransaction = new AtomicInteger();
public int withdrawal(int value) {
return money += value;
}
public int send(int value) {
return money -= value;
}
}
@Service
public class AccountService extends Thread {
private final AccountRepository accountRepository;
public AccountService(AccountRepository accountRepository) {
this.accountRepository = accountRepository;
}
public Iterable<Account> findAllAccount() {
return accountRepository.findAll();
}
public Account save(Account account) {
account.setMoney(10000);
return accountRepository.save(account);
}
public Long countAccount() {
return accountRepository.count();
}
public Account update(Account category) {
return accountRepository.save(category);
}
public void delete(Long id) {
accountRepository.deleteById(id);
}
@Transactional
public void transaction(Long accountIdOne, Long accountIdTwo, int value) {
Account accountOne = accountRepository.findById(accountIdOne).orElseThrow();
Account accountTwo = accountRepository.findById(accountIdTwo).orElseThrow();
synchronized (accountOne) {
synchronized (accountTwo) {
accountOne.withdrawal(value);
this.update(accountOne);
accountTwo.send(value);
this.update(accountTwo);
}
}
}
public void test() {
new Thread(new Runnable() {
@Override
public void run() {
while (Account.numberTransaction.get() < 10) {
int sleep = (int) (Math.random() * (2000 - 1000)) + 1000;
try {
transaction(1L, 2L, 1000);
Account.numberTransaction.incrementAndGet();
Thread.sleep(sleep);
} catch (InterruptedException exception) {
exception.printStackTrace();
}
}
}
}).start();
}
}
Тест:
@Test
void contextLoads() throws InterruptedException {
Account account = new Account();
Account account1 = new Account();
accountService.save(account);
accountService.save(account1);
for(int i = 0; i < accountService.countAccount(); i++) {
accountService.test();
accountService.join();
}
}
# По поводу того, что идет не так и как я это вижу, подключена БД и я вижу, что после того как происходит вызов метода test в тестовом слое, то ничего не изменяется, добавляются счета, но переводов между счетами не происходит.