WEB开发网
开发学院软件开发Java 使用 IBM FileNet P8 实现序列号分发器 阅读

使用 IBM FileNet P8 实现序列号分发器

 2009-12-09 00:00:00 来源:WEB开发网   
核心提示: ObjectStore 中的每个独立的可持久化对象都是以一个 Update Sequence Number (USN) 进行标记,这不是常规意义上的属性,使用 IBM FileNet P8 实现序列号分发器(8),但它的值是通过 IndependentlyPersistableObject.ge

ObjectStore 中的每个独立的可持久化对象都是以一个 Update Sequence Number (USN) 进行标记。这不是常规意义上的属性,但它的值是通过 IndependentlyPersistableObject.getUpdateSequenceNumber() 方法公开的。当每次 ObjectStore 中的对象被更新时,CE 服务器将自动递增 USN。当您从服务器获取一个对象时,USN 也被获取并传递到客户端。API 将 USN 作为 save() 对象的一部分发送回到服务器。如果发送的 USN 值与储存库中储存的值不匹配,CE 服务器就知道已经(由其他调用方)进行了更新,因此该对象已被获取。这是数据库调用乐观(optimistic)锁的简单方式。

如果 CE 服务器检测到交叉更改,它将合理地进行利用,这与合作锁特性不同。通过 CE API,您可以使用称为无获取实例化(在其他地方也提到)绕过服务器检查,但在这个用例中您要为此付出更多的努力。从本地在 API 中实例化一个对象而没有从服务器获取它称为无获取实例化。在这些情况中,USN 值有一个表示 CE 服务器跳过 USN 检查的特殊值。这有时被称为未保护更新。如果您稍后从服务器获取或刷新任何属性,也会获取当前 USN。

不过,在我们的例子中执行无获取实例化和未保护更新没有任何意义。要获取计数器属性的当前值,必须从服务器获取它。可能有人会恶意地通过未保护更新破坏计数器属性,但这种破坏也可以发生在常规的更新中。因此,这里没有出现新的威胁。因为用例存在语义,所以通过编写错误代码搞破坏的机会是很低的。

要利用 USN 检查和 CE 服务器的第一次写优先策略,您需要尝试在分发器对象中更新计数器,然后检查报告交叉更改的错误。清单 3 显示了该用例的一个例子。


清单 3. 第一次写优先
private static final String COUNTER_PROPERTY_NAME = "WjcCounter"; 
/** 
 * This property filter is used to minimize data returned in fetches and refreshes. 
 */ 
private static final PropertyFilter PF_COUNTER = new PropertyFilter(); 
static 
{ 
  PF_COUNTER.addIncludeProperty(1, null, null, COUNTER_PROPERTY_NAME, null); 
} 
 
/** 
 * Get the next value efficiently by exploiting First Writer Wins 
 */ 
public int getNextValue(boolean feelingUnlucky) 
{ 
  final Properties dispenserProperties = dispenser.getProperties(); 
  // Object might be updated by someone else, so try a few times 
  for (int attemptNumber=0; attemptNumber<10; ++attemptNumber) 
  { 
    // If cached data invalid, fetch the current value 
    // from the server. This also covers the fetchless 
    // instantiation case. 
    if (feelingUnlucky 
    || dispenser.getUpdateSequenceNumber() == null 
    || !dispenserProperties.isPropertyPresent(COUNTER_PROPERTY_NAME)) 
    { 
      // fetchProperties will fail if the USN doesn't match, so null it out 
      dispenser.setUpdateSequenceNumber(null); 
      dispenser.fetchProperties(PF_COUNTER); // R/T 
    } 
    int oldValue = dispenserProperties.getInteger32Value(COUNTER_PROPERTY_NAME); 
    int newValue = oldValue + 1; 
    dispenserProperties.putValue(COUNTER_PROPERTY_NAME, newValue); 
    try 
    { 
      // Because we use a refreshing save, the counter property's 
      // new value will be returned from the server. 
      dispenser.save(RefreshMode.REFRESH, PF_COUNTER); // R/T 
      return newValue; 
    } 
    catch (EngineRuntimeException ere) 
    { 
      ExceptionCode ec = ere.getExceptionCode(); 
      if (ec != ExceptionCode.E_OBJECT_MODIFIED) 
      { 
        // If we get an exception for any reason other than 
        // the object being concurrently modified, rethrow it. 
        throw ere; 
      } 
      // Someone else modified it. Invalidate our cached data and try again. 
      dispenser.setUpdateSequenceNumber(null); 
      dispenserProperties.removeFromCache(COUNTER_PROPERTY_NAME); 
      continue;  
    } 
  } 
  // too many iterations without success 
  throw new RuntimeException("Oops"); 
} 
 
/** 
 * Set by constructor or some other means. 
 * Fetchless instantiation is OK. 
 */ 
private final CustomObject dispenser; 

上一页  3 4 5 6 7 8 9 10  下一页

Tags:使用 IBM FileNet

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接