如何在没有额外请求的情况下保证成功删除或更新?

How can I guarantee successful deletion or update without extra request?

在某个微服务的服务层,我向另一个微服务发出POST请求,从数据库中删除一些记录:

@Override
public IdsResponse removeSomeStuff(IdsRequest request) throws NotFoundException {
    try {
        POST(SomeStuffEndpoint.createUrl(this.baseUri, REMOVE_SOME_STUFF), request, 
               IdsResponse.class);
    } catch(NotFoundException e) {
        logger.error("...", e);
        throw new NotFoundException(String.format("...: %s", e.getMessage()), e);
    }
    return new IdsResponse();
}

一个请求进来,比如在另一个微服务的端点:

@Path("/some-stuff")
public interface SomeStuffEndpoint {

    @POST
    @Path("/remove")
    Response removeSomeStuff(@Context MessageContext context);

    ...
}

在这个微服务的DAO层,我从数据库中删除(或更新)记录:

public class SomeStuffDaoImpl implements SomeStuffDao {
    private static final Logger logger = LoggerFactory.getLogger(SomeStuffDaoImpl.class);

    @Autowired
    SomeStuffMapper someStuffMapper;

    @Override
    public void removeSomeStuff(List<Long> someIds, List<Long> someAnotherIds) {
        try {
            someStuffMapper.removeSomeStuff(someIds, someAnotherIds);
        } catch (InvocationTargetException | PSQLException | BadSqlGrammarException e) {
            logger.error("...");
        }
    }
    ...
}   

我使用 MyBatis 3 作为持久性框架。删除如下:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 
                        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="some.company.appname.mservicename.model.mapper.SomeStuffMapper">

    <delete id="removeSomeStuff" parameterType="map">
        delete from some_stuff where some_id in
        <foreach collection="someIds" item="someId" 
                index="index" 
                open="(" separator="," close=")">
            #{someId}
        </foreach>

        and another_stuff in

        <foreach collection="someAnotherIds" item="someAnotherId" 
                 index="index" 
                 open="(" separator="," close=")">
            #{someAnotherId}
        </foreach>
    </delete>
... 

如何确保删除或更新成功,并且不提出额外的检查请求?

例如,请求包含不正确的标识符组合并且未找到记录(不抛出异常)?

您可以 return 一些信息作为 update/delete 的结果。在最简单的情况下,它可以是受影响的记录数。这样客户端就会知道没有记录被删除,例如。

为此,将映射器中 removeSomeStuff 的签名修改为 return int。 Mybatis 会return 条受影响的记录。这可以用于任何修改操作。

在某些情况下,return 有关受影响记录的更多信息(例如已删除记录的 ID)会有所帮助。您尚未指定正在使用的 RDBMS。在 postgres 中,您可以将 delete 转换为类似以下内容:

<select id="removeSomeStuff" parameterType="map" resultType="long" flushCache="true">

    delete from some_stuff where some_id in
    <foreach collection="someIds" item="someId" 
            index="index" 
            open="(" separator="," close=")">
        #{someId}
    </foreach>

    and another_stuff in

    <foreach collection="someAnotherIds" item="someAnotherId" 
             index="index" 
             open="(" separator="," close=")">
        #{someAnotherId}
    </foreach>
    RETURNING id
</select>