当前位置: 首页 > 知识库问答 >
问题:

具有远程服务调用的事务服务层

琴镜
2023-03-14

答案可能涵盖所有框架,但我对SpringMVC案例特别感兴趣。我正在重构一个访问内部数据库和远程服务的服务层。这些方法应该是事务性的,它们需要来自远程服务的数据。下面是类似的伪代码:

@Service
public class MyService {
    @Autowired
    private SomeRepository repository1;

    @Autowired
    private OtherRepository repository2;

    @Autowired
    private RemoteGateway remoteGateway;

    @Transactional
    public void updateState(Long id) {
        Item item1 = repository1.get(id)
        item1.setSomeVal(remoteGateway.getValue());
        repository1.save();

        repository2.doSomethingElse(item1.getOtherVal());
    }
}

这样更容易实现。但是有许多缺点,例如当远程服务调用失败时不必要地创建和回滚事务,由于远程服务调用而导致的事务更长,并且可能更复杂。我正在考虑将服务调用移动到单独的非事务性方法,并调用事务性方法,如下面的代码段所示

@Service
public class MyService {
    @Autowired
    private SomeRepository repository1;

    @Autowired
    private OtherRepository repository2;

    @Autowired
    private RemoteGateway remoteGateway;

    public SomeType updateState(Long id) {
        SomeType valueFromRemote = remoteGateway.getValue();
        updateState(id, valueFromRemote);
    }

    @Transactional
    public void updateState(Long id, SomeType valueFromRemote) {
        Item item1 = repository1.get(id)
        item1.setSomeVal(valueFromRemote);
        repository1.save();

        repository2.doSomethingElse(item1.getOtherVal());
    }
}

假设remoteGateway具有缓存、适当的超时和断路器,这样就不会无限期地挂起,并且在缓存间隔内已经请求值时会更快,重构有意义吗?或者什么是更好的设计决策?

共有1个答案

巴英韶
2023-03-14

我认为如果事务的长度是一个问题,并且在调用它之前知道在事务方法中需要什么值,那么这是一个很好的重构。如果需要从远程服务中获取许多值,可以考虑异步调用服务。

这里只有一个问题——如果您使用默认的“代理”事务支持方式,那么如果您调用同一个bean的方法,它将不起作用。在您的情况下,从updateState(Long id)调用updateState(id,valueFromRemote)不会在事务中运行,因为不会执行代理代码(调试事务方法时,您可以在调用堆栈中看到代理支持)。要想避开它,你可以

  • 将事务方法移动到另一个bean
 类似资料:
  • 主要内容:1.概述,2. HttpClientConnection,3. HessianProtocol1.概述 Hessian 协议用于集成 Hessian 的服务,Hessian 底层采用 Http 通讯,采用 Servlet 暴露服务,Dubbo 缺省内嵌 Jetty 作为服务器实现。 本文涉及类图(红圈部分)如下: 2. HttpClientConnection 实现 HessianConnection 接口,HttpClient 连接器实现类。 2.1 HttpClientConnec

  • 主要内容:1. 概述,2. AbstractProxyProtocol,3. HttpProtocol1. 概述 基于 HTTP 表单的远程调用协议,采用 Spring 的 HttpInvoker 实现 涉及类图(红圈部分)如下: 2. AbstractProxyProtocol 现 AbstractProtocol 抽象类,Proxy 协议抽象类。为 HttpProtocol 、RestProtocol 等子类,提供公用的服务暴露、服务引用的公用方法,同时定义了如下抽象方法,用于不同子类协议实

  • 服务调用失败 KernalEvent::SERVICE_FAIL事件 在框架层,调用servcie时,会抛出KernalEvent::SERVICE_FAIL事件,你可以监听该事件,做数据上报处理,请以异步方式上报 配置config/lister.php中的事件监听器 示例 <?php namespace src\Web\Listeners; class ServiceFailListener e

  • 在异步HTTP SERVER中使用服务 全局方法service_center() 使用service_center($service)获取服务地址,然后使用call()方法调用公开的服务方法 $service = (yield service_center('User')); $user = (yield $service->call("User::getUser", ['id'

  • 我必须使用SpringBoot2.0.5从web应用程序构建中调用远程RESTendpoint 我可以使用HttpURLConnection,但由于Spring使用RestTemplate,我检查了它是什么,发现它很快就会被弃用: https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/clien

  • 尝试远程启动服务时遇到奇怪的行为。 编辑:我进一步研究了这个问题,发现只有在尝试运行我的特定服务时才会出现这种情况。这意味着我的服务必须从已经登录的用户的会话中运行(这就是为什么如果我之前使用mstsc访问服务器,它仍然可以工作)。所以我想我的新问题是--有没有一种方法可以让我从PowerShell登录到远程机器? 多谢了。