Spring 单个事务中的ArgumentResolver?
我想知道是否有一种方法可以将Spring 单个事务中的ArgumentResolver?,spring,hibernate,spring-mvc,transactions,Spring,Hibernate,Spring Mvc,Transactions,我想知道是否有一种方法可以将@PathVariables或@modeldattributes的所有参数解析器封装到一个事务中?我们已经在使用OEMIV过滤器,但是spring/hibernate产生了太多的事务(如果它们没有包装在服务类中,则每个选择一个事务,例如pathvariable解析器就是这样) 虽然系统仍然相当快,但我认为这是不必要的,也与体系结构的其余部分不一致 让我解释一下: 假设我有一个包含两个实体的请求映射,并且转换基于StringToEntityConverter 如果我们支
@PathVariables
或@modeldattributes
的所有参数解析器封装到一个事务中?我们已经在使用OEMIV过滤器,但是spring/hibernate产生了太多的事务(如果它们没有包装在服务类中,则每个选择一个事务,例如pathvariable解析器就是这样)
虽然系统仍然相当快,但我认为这是不必要的,也与体系结构的其余部分不一致
让我解释一下:
假设我有一个包含两个实体的请求映射,并且转换基于StringToEntityConverter
如果我们支持GET:http://localhost/app/link/User_231/Item_324
@RequestMapping("/link/{user}/{item}", method="POST")
public String linkUserAndItem(@PathVariable("user") User user, @PathVariable("item") Item item) {
userService.addItem(user, item);
return "linked";
}
@Converter
// simplified
public Object convert(String classAndId) {
return entityManager.find(getClass(classAndId), getId(classAndId));
}
UserService.addItem()
方法是事务性的,因此这里没有问题
但是:
实体转换器在调用控制器
之前根据数据库解析用户和项目,从而创建两个选择,每个选择都在自己的事务中运行。然后我们有了@modeldattribute
方法,这些方法可能还会再次发出一些选择,每个方法都会产生一个事务
这就是我想要改变的。我想创建一个只读事务
我找不到任何方法来拦截/监听/等等。。。借助于弹簧
首先,我想覆盖RequestMappingHandlerAdapter
,但解析程序调用在invokeHandleMethod
方法中“隐藏”得很好
ModelFactory
不是Springbean,因此我也不能编写拦截器
因此,目前我只看到完全替换RequestMappingHandlerAdapter
的方法,但我确实希望避免这种情况
还有想法 对我来说,这似乎是设计上的失败。OEMIV通常是你做错了的标志™. 相反,要:
@RequestMapping("/link/User_{userId}/Item_{itemId}", method="POST")
public String linkUserAndItem(@PathVariable("userId") Long userId,
@PathVariable("itemId") Long itemId) {
userService.addItem(userId, itemId);
return "linked";
}
服务层负责获取和操作实体。这种逻辑不属于控制器。虽然我可以理解您的OEMIV观点,但我不得不不同意。人们赞成或反对这种做法的可能性大约为50%;)对于我和我的团队来说,请求本身就是一个工作单元。要么失败,要么成功。但这不是问题的重点。我们只是用来呈现页面的OEMIV过滤器。如果出现错误,这仍然是正确处理的。我坚定地支持“观点应该是愚蠢的”阵营。将视图实际需要的所有内容作为简单变量(最好是字符串)传入。然后您的视图是精简的,控制器是精简的,服务调用是事务性的,并且执行真正的工作。考虑到SpringCore中缺乏支持,您显然在做一些非标准的事情;也许你应该重新考虑这一点。@MartinFrey我想到了一个可能的解决方案,它不涉及改变一切:你可以使用
spring aop
在你的控制器方法上做一个切入点,并在那里手动启动一个事务,或者可能用@Transactional
注释aop方法。谢谢你的输入。到目前为止,我认为我们没有做错什么。modelattribute方法使用服务和存储库解析实体。然后,它将模型传递给requestmapping方法,该方法使用服务完成它的一部分。只是每个modelattribute方法都可能使用一个需要事务的服务调用。因此,我希望将modelattributeresolver整体包装,而不是逐个包装。这就是spring不支持它的地方,例如,我还找不到AOP切入点。请尝试类似于@Transactional@Around(“myapp.Controller.method()”)
的方法。