1.首先要在pom.xml配置中加入spring-retry的依赖:
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
</dependency>
2.在启动类中加入重试注解@EnableRetry。
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.retry.annotation.EnableRetry;
@EnableRetry //重试注解
@MapperScan("com.batis.mapper")
@SpringBootApplication
public class BatisApplication {
public static void main(String[] args) {
SpringApplication.run(BatisApplication.class, args);
}
}
3.新建重试接口RetryService和实现类RetryServiceImpl
public interface RetryService {
void retryTransferAccounts(int fromAccountId, int toAccountId, float money) throws Exception;
}
接口实现
import com.batis.mapper.AccountMapper;
import com.batis.model.Account;
import com.batis.service.RetryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Recover;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class RetryServiceImpl implements RetryService {
@Autowired
private AccountMapper accountMapper;
@Transactional
@Retryable(value = Exception.class, maxAttempts = 3, backoff = @Backoff(delay = 3000, multiplier = 1, maxDelay = 10000))
@Override
public void retryTransferAccounts(int fromAccountId, int toAccountId, float money) throws Exception {
Account fromAccount = accountMapper.findOne(fromAccountId);
fromAccount.setBalance(fromAccount.getBalance() - money);
accountMapper.update(fromAccount);
int a = 2 / 0;
Account toAccount = accountMapper.findOne(toAccountId);
toAccount.setBalance(toAccount.getBalance() + money);
accountMapper.update(toAccount);
throw new Exception();
}
@Recover
public void recover(Exception e) {
System.out.println("回调方法执行!!!");
}
}
@Retryable:标记当前方法会使用重试机制
value:重试的触发机制,当遇到Exception异常的时候,会触发重试
maxAttempts:重试次数(包括第一次调用)
delay:重试的间隔时间
multiplier:delay时间的间隔倍数
maxDelay:重试次数之间的最大时间间隔,默认为0,如果小于delay的设置,则默认为30000L
@Recover:标记方法为回调方法,传参与@Retryable的value值需一致
4.新建重试控制器类RetryController
import com.batis.service.RetryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/retry")
public class RetryController {
@Autowired
private RetryService retryService;
@RequestMapping(value = "/transfer", method = RequestMethod.GET)
public String transferAccounts() {
try {
retryService.retryTransferAccounts(1, 2, 200);
return "ok";
} catch (Exception e) {
return "no";
}
}
}