@Service
public class TransferService {

    @Autowired
    TransferRepository transferRepository;
    @Autowired
    AccountRepository accountRepository;


    @Transactional(REQUIRES_NEW)
    public void transfer(Account fromAccount, Account toAccount, 
        BigDecimal amount) throws InterruptedException {


    fromAccount.setBalance(fromAccount.getBalance().subtract(amount));
    accountRepository.save(fromAccount);

    if(fromAccount.getId() == 1L){
        Thread.currentThread().sleep(10000);
    }

    toAccount.setBalance(toAccount.getBalance().add(amount));
    accountRepository.save(toAccount);

    transferRepository.save(new Transfer(fromAccount, toAccount,amount));
    }
}

db表 Account 中的初始状态:

id | balance | version    
1  | 100     | 0    
2  | 100     | 0

Transfer 表是空的 .

我打电话的时候:

1. transfer(account1, account2, 10);  
 2. transfer(account2, account1, 20);

db table Account

id | balance | version    
1  | 120     | 0    
2  | 80      | 0

db table Transfer

id | ammount | fromAccountId | toAccountId    
1  | 20      | 2             | 1        
2  | 10      | 1             | 2

日志清楚地表明它将要回滚: Transfer#2Account#2Account#1 ,但它不会仅仅回收账户但是ID 2的转移是应该回滚的 .

任何帮助超级赞赏!!!

日志:

2018-01-14 12:14:27.652 DEBUG 16006 --- [nio-8080-exec-7] osorm.jpa.JpaTransactionManager在EntityManager上发布JPA事务[SessionImpl(PersistenceContext [entityKeys = [EntityKey [com.erabanq.entity] .Transfer#2],EntityKey [com.erabanq.entity.Account#2],EntityKey [com.erabanq.entity.Account#1]],collectionKeys = []]; ActionQueue [insertions = ExecutableList 更新= ExecutableList deletions = ExecutableList orphanRemovals = ExecutableList collectionCreations = ExecutableList collectionRemovals = ExecutableList collectionUpdates = ExecutableList collectionQueuedOps = ExecutableList unresolvedInsertDependencies = null])] 2018-01-14 12:14:27.657 ERROR 16006 --- [nio-8080-exec-7] ohiExceptionMapperStandardImpl:HHH000346:托管刷新期间出错[批量更新返回意外行从更新[0]计数;实际行数:0;预期:1] 2018-01-14 12:14:27.658 INFO 16006 --- [nio-8080-exec-7] ohejbinternal.AbstractBatchImpl:HHH000010:在批量发布时它仍然包含JDBC语句2018-01-14 12 :14:27.678 DEBUG 16006 --- [nio-8080-exec-7] osorm.jpa.JpaTransactionManager:在提交异常后启动事务回滚org.springframework.orm.ObjectOptimisticLockingFailureException:批量更新从update [0]返回意外的行数;实际行数:0;预期:1;嵌套异常是org.hibernate.StaleStateException:批量更新从update [0]返回了意外的行数;实际行数:0;预期:1

这是DB日志:

>START...............................
>2018-01-14T15:48:03.913784Z         8 Query     set session transaction read only    
>2018-01-14T15:48:03.913963Z         8 Query     SET autocommit=0    
>2018-01-14T15:48:03.921491Z         8 Query     select account0_.id as id1_0_0_, account0_.balance as balance2_0_0_, account0_.version as version3_0_0_ from account account0_ where account0_.id=1    
>2018-01-14T15:48:03.930767Z         8 Query     commit    
>2018-01-14T15:48:03.930929Z         8 Query     SET autocommit=1    
>2018-01-14T15:48:03.931281Z         8 Query     select @@session.tx_read_only    
>2018-01-14T15:48:03.931607Z         8 Query     set session transaction read write    
>2018-01-14T15:48:03.932052Z         8 Query     set session transaction read only    
>2018-01-14T15:48:03.932173Z         8 Query     SET autocommit=0    
>2018-01-14T15:48:03.932750Z         8 Query     select account0_.id as id1_0_0_, account0_.balance as balance2_0_0_, account0_.version as version3_0_0_ from account account0_ where account0_.id=2    
>2018-01-14T15:48:03.933613Z         8 Query     commit    
>2018-01-14T15:48:03.933744Z         8 Query     SET autocommit=1    
>2018-01-14T15:48:03.933968Z         8 Query     select @@session.tx_read_only    
>2018-01-14T15:48:03.934134Z         8 Query     set session transaction read write    
>2018-01-14T15:48:03.937186Z         8 Query     SET autocommit=0    
>2018-01-14T15:48:11.995802Z         9 Query     set session transaction read only    
>2018-01-14T15:48:11.996386Z         9 Query     SET autocommit=0    
>2018-01-14T15:48:11.999184Z         9 Query     select account0_.id as id1_0_0_, account0_.balance as balance2_0_0_, account0_.version as version3_0_0_ from account account0_ where account0_.id=2    
>2018-01-14T15:48:12.002778Z         9 Query     commit    
>2018-01-14T15:48:12.003217Z         9 Query     SET autocommit=1    
>2018-01-14T15:48:12.003848Z         9 Query     select @@session.tx_read_only    
>2018-01-14T15:48:12.004822Z         9 Query     set session transaction read write    
>2018-01-14T15:48:12.006758Z         9 Query     set session transaction read only     
>2018-01-14T15:48:12.008320Z         9 Query     SET autocommit=0    
>2018-01-14T15:48:12.012266Z         9 Query     select account0_.id as id1_0_0_, account0_.balance as balance2_0_0_, account0_.version as version3_0_0_ from account account0_ where account0_.id=1    
>2018-01-14T15:48:12.015808Z         9 Query     commit    
>2018-01-14T15:48:12.016214Z         9 Query     SET autocommit=1    
>2018-01-14T15:48:12.016792Z         9 Query     select @@session.tx_read_only    
>2018-01-14T15:48:12.017278Z         9 Query     set session transaction read write    
>2018-01-14T15:48:12.018332Z         9 Query     SET autocommit=0
>2018-01-14T15:48:12.078209Z         9 Query     insert into transfer (ammount, from_id, to_id, type) values (15, 2, 1, null)    
>2018-01-14T15:48:12.082738Z         9 Query     update account set balance=85.00, version=1 where id=2 and version=0    
>2018-01-14T15:48:12.084494Z         9 Query     update account set balance=115.00, version=1 where id=1 and version=0    
>2018-01-14T15:48:12.084946Z         9 Query     commit    
>2018-01-14T15:48:12.085086Z         9 Query     SET autocommit=1    
>2018-01-14T15:48:13.952199Z         8 Query     insert into transfer (ammount, from_id, to_id, type) values (10, 1, 2, null)    
>2018-01-14T15:48:13.954992Z         8 Query     update account set balance=90.00, version=1 where id=1 and version=0    
>2018-01-14T15:48:13.956614Z         8 Query     rollback    
>2018-01-14T15:48:13.957371Z         8 Query     SET autocommit=1

我使用的是Spring Data JPA 2.1,hibernate-core-5.2.12.Final.jar