一段有意思的代码,关于事务和测试
Sort sort = new Sort(Direction.ASC, "id");
int offset = 0;
int limit = 50;
Page<User>[] users = new Page[1];
do {
users[0] = this.userRepository.findAll(spec, new OffsetRequest(offset, limit, sort));
//offset += users[0].getContent().size(); 使用transactionTemplate,查询的时候删除自身的数据,offset需要从0算起
Boolean deleted = transactionTemplate.execute(new TransactionCallback<Boolean>() {
@Override
public Boolean doInTransaction(TransactionStatus transactionStatus) {
users[0].getContent().forEach(user -> {
input.getTags().forEach(tagId -> {
tagXrefRepository.deleteByUserAndTag(entId, user.getId(), tagId);
});
});
return true;
}
});
Test模块:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = {UserServiceApp.class, RepositoryUtils.class})
@Transactional
public class UserManServiceTest {
@Test
@Rollback(false)
public void testQueryAndCancelTagging() {
QueryAndTaggingRequestDto request = new QueryAndTaggingRequestDto().entId(2)
.queryAndTaggingInput(new QueryAndTaggingInputDto().platId(1)
.tags(Arrays.asList(10001, 10002)));
CommonResponseDto responseDto = service.queryAndCancelTagging(request);
assertTrue(responseDto.getSuccess());
}
}
测试时,因为事务在对象创建时已经创建,@Transactional
propagation属性默认为Propagation.REQUIRED。其中,
TransactionDefinition.PROPAGATION_REQUIRED:如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。这是默认值。
TransactionDefinition.PROPAGATION_REQUIRES_NEW:创建一个新的事务,如果当前存在事务,则把当前事务挂起。
TransactionDefinition.PROPAGATION_SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。
TransactionDefinition.PROPAGATION_NOT_SUPPORTED:以非事务方式运行,如果当前存在事务,则把当前事务挂起。
TransactionDefinition.PROPAGATION_NEVER:以非事务方式运行,如果当前存在事务,则抛出异常。
TransactionDefinition.PROPAGATION_MANDATORY:如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。
TransactionDefinition.PROPAGATION_NESTED:如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于TransactionDefinition.PROPAGATION_REQUIRED。
所以,后面的分批删除操作是在这个事务中进行操作
在线上环境,
transacionTemplate.execute(new TransactionCallback<Boolean>() {
@Override
public Boolean doInTransaction(TransactionStatus transactionStatus)
TransactionCallback,顾名思义,就是事务回调然后查到TransactionCallback。这个接口中只有一个方法,doInTransaction(TransactionStatus status) ;
就是在一个事务中需要做的事情都包括这这个方法中了。
而这个doInTransaction 又传入了一个参数,这次是 TransactionStatus,顾名思义,就是事务状态。 TransactionStatus 是一个接口,
hasSavepoint() ;
isCompleted() ;
isNewTransaction() ;
setRollbackOnly() ;