1、編排腳本中指定的ServiceName,報找不到bean
腳本片段:
{
...
"States": {
"ServiceA": {
"Type": "ServiceTask",
"ServiceName": "IServiceASeata",
"ServiceMethod": "run",
"CompensateState": "CompensateServiceA",
...
需要在feign接口上指定quilifier,屬性值是服務名
@FeignClient(value = "servicea", qualifier = "IServiceASeata")
public interface IServiceASeata extends IservicewithCancel {
}
2、服務中拋異常后,Seata無法控制事務回滾
debug發(fā)現(xiàn)Seata拿不到異常,異常被feign拿走后直接拋出來了,所以需要重新實現(xiàn)feign的異常處理
public class FeignExceptionConfiguration {
private static final Logger LOG = LoggerFactory.getLogger(FeignExceptionConfiguration.class);
@Bean
public ErrorDecoder errorDecoder() {
return new UserErrorDecoder();
}
/**
* 重新實現(xiàn)feign的異常處理,捕捉restful接口返回的json格式的異常信息
*
*/
public class UserErrorDecoder implements ErrorDecoder {
public Exception decode(String methodKey, Response response) {
Exception exception = null;
ObjectMapper mapper = new ObjectMapper();
//空屬性處理
mapper.setSerializationInclusion(JsonSerialize.Inclusion.NON_EMPTY);
//設置輸入時忽略在JSON字符串中存在但Java對象實際沒有的屬性
mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
//禁止使用int代表enum的order來反序列化enum
mapper.configure(DeserializationConfig.Feature.FAIL_ON_NUMBERS_FOR_ENUMS, true);
try {
String json;
//增加判空
if(response.body() == null){
json = "{ \"body\": \"empty body\"}";
}else {
json = Util.toString(response.body().asReader());
}
exception = new RuntimeException(json);
if (StringUtils.isEmpty(json)) {
return null;
}
FeignFaildResult result = mapper.readValue(json, FeignFaildResult.class);
// 業(yè)務異常包裝成自定義異常類MyException
if (result.getStatus() != HttpStatus.OK.value()) {
exception = new MyException(result.getMessage(),result.getStatus());
}
} catch (IOException ex) {
LOG.error(ex.getMessage(), ex);
}
return exception;
}
}
}
public class FeignFaildResult {
private String message;
private int status;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
}
然后在接口上指定這個處理:
@FeignClient(value = "servicea", qualifier = "IServiceASeata",configuration = FeignExceptionConfiguration.class)
public interface IServiceASeata extends IservicewithCancel {
}
參考:
http://www.itdecent.cn/p/b2a0168afeba
異常處理的代碼基本是原樣照搬,增加了對response.body的判空,不然我的場景會報空指針