如何在没有额外请求的情况下保证成功删除或更新?
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>
在某个微服务的服务层,我向另一个微服务发出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>