S
S
Saintka2021-08-15 12:49:02
Java
Saintka, 2021-08-15 12:49:02

Why do I get an incorrect change in values ​​when working with streams?

I create n independent streams, after the execution of the transaction method, the values ​​​​should change (money should go from one account to another), but after execution, the values ​​\u200b\u200bdo not change. By default, in the save method, I add 10000 to each account. 9 transactions should occur and after that the program should end.

@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:
@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();

    }
}


# Regarding what is going wrong and as I see it, the database is connected and I see that after the test method is called in the test layer, nothing changes, accounts are added, but transfers between accounts do not occur.

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question