如何阅读将单独的数据库事务中的内容项目写入请求

问题描述:

我的Orchard应用程序中有一个采购订单内容类型。其他属性中包含PurchaseOrderNumber。采购订单号是在用户首次保存采购订单时分配的。我使用自定义控制器和视图来执行采购订单CRUD操作。如何阅读将单独的数据库事务中的内容项目写入请求

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

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

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

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

或者是否有不同的模式,我应该使用?

+0

为什么要在订单创建之前拥有订单号**?为什么不在创建订单时分配号码,然后将其显示给用户?这样你永远不会有重复 – devqon

+0

该号码只在用户创建订单时分配。问题是,如果两个用户点击约保存按钮。每个用户最终可能会得到相同的采购订单号。 –

查看Orchard.Tasks.Locking.Services.DistributedLockService类后,我想出了它。您需要依赖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 ""; 
    } 
    } 
}