@Saintka

Почему получается некорректное изменение значений при работе с потоками?

Создаю 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 в тестовом слое, то ничего не изменяется, добавляются счета, но переводов между счетами не происходит.
  • Вопрос задан
  • 37 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы