@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#2
, Account#2
和 Account#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