Spring + Hibernate - 使用@Transactional方法

时间:2015-11-15 12:53:34

标签: multithreading spring hibernate concurrency spring-transactions

我遇到多个线程同时访问某些事务方法的问题

要求是检查一个帐户是否已经存在或以其他方式创建它,下面代码的问题是如果两个线程并行执行accountDao.findByAccountRef()方法并且具有相同的帐户引用,并且如果他们没有找到该帐户,则两者都是尝试创建一个相同的帐户,这将是一个问题, 任何人都可以向我提出一些如何克服这种情况的建议吗?

代码粘贴在

下面

由于 拉梅什

@Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED) 
@Override
    public void createAccount(final String accountRef, final Money amount) {

        LOG.debug("creating account with reference {}", accountRef);

        if (isNotBlank(accountRef)) {
            // only create a new Account if it doesn't exist already for the given reference
            Optional<AccountEO> accountOptional = accountDao.findByAccountRef(accountRef);
            if (accountOptional.isPresent()) {
                throw new AccountException("Account already exists for the given reference %s", accountRef);
            }
            // no such account exists, so create one now
            accountDao.create(newAccount(accountRef, neverNull(amount)));
        } else {
            throw new AccountException("account reference cannot be empty");
        }
    }

1 个答案:

答案 0 :(得分:1)

如果您希望系统在有少数人使用它时执行,您可以使用乐观锁定的概念(我知道这里没有锁定)。

在创建时,这会尝试插入新帐户,如果由于重复的主键而导致异常(您需要从异常中检查此内容),那么您知道该帐户是已经创建了。

简而言之,你乐观地尝试创建行,如果失败,你知道那里已经有了。