如何在单独的数据库事务中将内容项读写到请求的内容项

How do I read write a content item in a separate database transaction to that of the request

我的 Orchard 应用程序中有一个采购订单内容类型。在其他属性中,它有一个 PurchaseOrderNumber。采购订单号是在用户第一次保存采购订单时分配的。我使用自定义控制器和视图来实现采购订单 CRUD 操作。

我有一个采购订单编号定义部分,它附加到公司内容类型,其中保存了下一个采购订单编号、前缀和填充。因此,当系统生成下一个采购订单编号时,前缀(例如 PO)与下一个编号(例如 123)和填充(例如 5)一起使用以生成一个字符串 - 例如PO00123。

当采购订单编号生成时,存储在附加到公司内容项目的采购订单定义部分中的下一个采购订单编号被递增并保存,以便当用户创建另一个采购订单时,它将被分配下一个编号.

我的挑战是如果两个用户同时创建新的采购订单,如何防止分配重复的采购订单编号。

我正在考虑创建一个 ISingletonDependency,它使用 lock (_lock) {...} 来包装将生成下一个数字的代码。通过这种方式,多个请求可以请求下一个号码并始终获得下一个唯一号码。我该如何实现呢?我不知道如何访问具有自己的数据库事务的 IContentManager。

或者我应该使用其他模式吗?

看了Orchard.Tasks.Locking.Services.DistributedLockServiceclass我就明白了。您需要依赖 ILifetimeScope,然后解析 ITransactionManager 和 IContentManager。

lock (_lock) {
  using (var childLifetimeScope = _lifetimeScope.BeginLifetimeScope()) {
    var transactionManager = childLifetimeScope.Resolve<ITransactionManager>();
    var contentManager = childLifetimeScope.Resolve<IContentManager>();
    try {
      transactionManager.RequireNew(IsolationLevel.Serializable);
      var contentItem = contentManager.GetLatest(contentItemId);

      var number = CompileNewNumber(contentItem);

      contentManager.Publish(contentItem);
      return number;
    }
    catch (Exception exception) {
      Logger.Error(exception, "Error compiling next number.");
      transactionManager.Cancel();
      return "";
    }
  }
}