Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/gwt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java GWT RequestFactory是否支持乐观并发控制的实现?_Java_Gwt_Requestfactory - Fatal编程技术网

Java GWT RequestFactory是否支持乐观并发控制的实现?

Java GWT RequestFactory是否支持乐观并发控制的实现?,java,gwt,requestfactory,Java,Gwt,Requestfactory,在GWT应用程序中,我提供用户可以编辑的项目。使用GWT请求工厂加载和保存项目。我现在想要实现的是,如果两个用户同时编辑一个条目,则首先保存的用户将以乐观并发控制的方式获胜。这意味着,当第二个用户保存其更改时,请求工厂后端会识别到存储在后端的项目的版本或存在已更改,因为它已传输到客户端,请求工厂/后端会以某种方式阻止项目更新/保存 我试图在用于保存项目的服务方法中实现这一点,但这不起作用,因为请求工厂将从后端检索的项目交给应用用户更改,这意味着这些项目的版本是来自后端的当前版本,比较没有意义 在

在GWT应用程序中,我提供用户可以编辑的项目。使用GWT请求工厂加载和保存项目。我现在想要实现的是,如果两个用户同时编辑一个条目,则首先保存的用户将以乐观并发控制的方式获胜。这意味着,当第二个用户保存其更改时,请求工厂后端会识别到存储在后端的项目的版本或存在已更改,因为它已传输到客户端,请求工厂/后端会以某种方式阻止项目更新/保存

我试图在用于保存项目的服务方法中实现这一点,但这不起作用,因为请求工厂将从后端检索的项目交给应用用户更改,这意味着这些项目的版本是来自后端的当前版本,比较没有意义

在请求工厂处理中是否有我可以利用的钩子来实现请求的行为?还有其他想法吗?或者我必须改用GWT-RPC吗…

否:

在建议的API实现之前(
EntityLocator
,在注释1中,但我不清楚如何从其序列化形式重建版本信息),您必须以某种方式将版本发送回服务器。
正如我在本期中所说,这不能通过简单地在代理中提供version属性并设置它来实现;但是您可以添加另一个属性:获取它将始终返回
null
(或类似的不存在的值),这样在客户端将其设置为“true”版本属性的值将始终产生更改,从而保证该值将作为“property diff”的一部分发送到服务器;在服务器端,您可以在setter(当RequestFactory应用“property diff”并调用setter时,如果值与“true”版本不同,则抛出异常)或服务方法中处理事情(将从客户机发送的版本(从不同的getter获得的版本与映射到客户机上的版本不同,因为必须始终返回
null
)与对象的“真实”版本进行比较,如果不匹配,则引发错误)

比如:

@ProxyFor(MyEntity.class)
interface MyEntityProxy extends EntityProxy {
   String getServerVersion();
   String getClientVersion();
   void setClientVersion(String clientVersion);
   …
}

@Entity
class MyEntity {
   private String clientVersion;
   @Version private String serverVersion;

   public String getServerVersion() { return serverVersion; }
   public String getClientVersion() { return null; }
   public void setClientVersion(String clientVersion) {
      this.clientVersion = clientVersion;
   }

   public void checkVersion() {
      if (Objects.equal(serverVersion, clientVersion)) {
         throw new OptimisticConcurrencyException();
      }
   }
}

请注意,我没有对此进行测试,这是纯理论。

我们在应用程序中提出了另一种乐观锁定的解决方案。由于无法通过代理本身传递版本(),因此我们将通过HTTP GET参数将其传递给请求工厂

在客户机上:

MyRequestFactory factory = GWT.create( MyRequestFactory.class );
RequestTransport transport = new DefaultRequestTransport() {
        @Override
        public String getRequestUrl() {
            return super.getRequestUrl() + "?version=" + getMyVersion();
        }
    };
factory.initialize(new SimpleEventBus(), transport);
在服务器上,我们创建一个ServiceLayerDecorator,并从
RequestFactoryServlet.getThreadLocalRequest()
读取版本:

公共静态类myServiceLayerCorator扩展ServiceLayerCorator{
@凌驾
公共最终T loadDomainObject(最终类clazz,最终对象domainId){
HttpServletRequest threadLocalRequest=RequestFactoryServlet.getThreadLocalRequest();
字符串clientVersion=threadLocalRequest.getParameter(“version”);
T domainObject=super.loadDomainObject(clazz,domainId);
字符串serverVersion=((HasVersion)domainObject.getVersion();
if(versionMismatch(serverVersion,clientVersion))
报告(“版本错误!”);
返回域对象;
}
}
优点是在RF对域对象应用任何更改之前调用
loadDomainObject()


在我们的例子中,我们只跟踪一个实体,所以我们使用一个版本,但这种方法可以扩展到多个实体。

感谢指针和建议:)如果在使用我的解决方案之前,没有可用的解决方案,我将尝试此方法或报告中的组合id解决方法。还有很多与facebook相关的事情要做,所以这仍然需要相当长的时间:DLooks对我来说是一个非常好的解决方法。唯一需要解决的问题是自动查找要在客户端发送的实体版本。
public static class MyServiceLayerDecorator extends ServiceLayerDecorator {
  @Override
  public final <T> T loadDomainObject(final Class<T> clazz, final Object domainId) {
    HttpServletRequest threadLocalRequest = RequestFactoryServlet.getThreadLocalRequest();
    String clientVersion = threadLocalRequest.getParameter("version") );

    T domainObject = super.loadDomainObject(clazz, domainId);
    String serverVersion = ((HasVersion)domainObject).getVersion();

    if ( versionMismatch(serverVersion, clientVersion) )
      report("Version error!");         

    return domainObject;
  }
}