Acumatica 错误90:另一个进程已更新';BAccount';记录。您的更改将丢失
我试图更新一个BAccount记录两次,但第二次它抛出上述异常 在异常中向下钻取时,我还看到PXLockViolationException。我猜这是在进行某种交易 基本上,我使用CustomerMain图添加客户记录 使用graph.Actions.Save()保存记录 随后在同一过程中,我使用VendorMaint图添加同一客户的供应商记录(Baccount),当我坚持更改时,它会抛出该错误 任何帮助都将不胜感激Acumatica 错误90:另一个进程已更新';BAccount';记录。您的更改将丢失,acumatica,Acumatica,我试图更新一个BAccount记录两次,但第二次它抛出上述异常 在异常中向下钻取时,我还看到PXLockViolationException。我猜这是在进行某种交易 基本上,我使用CustomerMain图添加客户记录 使用graph.Actions.Save()保存记录 随后在同一过程中,我使用VendorMaint图添加同一客户的供应商记录(Baccount),当我坚持更改时,它会抛出该错误 任何帮助都将不胜感激 干杯添加客户后 清除图表 通过设置当前值将客户记录加载到图表中 然后添加其他详
干杯添加客户后
问题源于您试图保留过时的DAC。原因是内存中有同一DAC的多个实例。一旦您持久化更新的实例,如果您试图持久化过时的实例,您将得到一个异常。为了理解为什么要使用多个实例,我们需要了解所使用的不同类之间的关系 类AR.Customer和AP.Vendor都直接从CR.BAccount继承 客户声明:
public partial class Customer : BAccount, PX.SM.IIncludable
卖方声明
public partial class Vendor : CR.BAccount, PX.SM.IIncludable
CR.BAccount的不同可能状态为
- 前景
- 顾客
- 卖主
- 客户和供应商(合并)
public PXAction<BAccount> converToVendor;
[PXUIField(DisplayName = Messages.ConvertToVendor, MapEnableRights = PXCacheRights.Select, MapViewRights = PXCacheRights.Select)]
[PXButton(ImageKey = PX.Web.UI.Sprite.Main.Process)]
public virtual IEnumerable ConverToVendor(PXAdapter adapter)
{
BAccount bacct = this.BAccount.Current;
if (bacct != null && (bacct.Type == BAccountType.ProspectType || bacct.Type == BAccountType.CustomerType))
{
Save.Press();
AP.VendorMaint editingBO = PXGraph.CreateInstance<AP.VendorMaint>();
AP.VendorR vendor = (AP.VendorR)editingBO.BAccount.Cache.Extend<BAccount>(bacct);
editingBO.BAccount.Current = vendor;
vendor.Type = (bacct.Type == BAccountType.ProspectType) ? BAccountType.VendorType : BAccountType.CombinedType;
LocationExtAddress defLocation = editingBO.DefLocation.Select();
editingBO.DefLocation.Cache.RaiseRowSelected(defLocation);
string locationType = (bacct.Type == BAccountType.ProspectType) ? LocTypeList.VendorLoc : LocTypeList.CombinedLoc;
editingBO.InitVendorLocation(defLocation, locationType);
defLocation = editingBO.DefLocation.Update(defLocation);
foreach (Location iLoc in editingBO.IntLocations.Select())
{
if (iLoc.LocationID != defLocation.LocationID)
{
editingBO.InitVendorLocation(iLoc, locationType);
editingBO.IntLocations.Update(iLoc);
}
}
editingBO.Answers.CopyAttributes(vendor, bacct);
throw new PXRedirectRequiredException(editingBO, Messages.EditVendor);
}
return adapter.Get();
}
公共PXAction转换器;
[PXUIField(DisplayName=Messages.ConvertToVendor,MapEnableRights=PXCacheRights.Select,MapViewRights=PXCacheRights.Select)]
[PXButton(ImageKey=PX.Web.UI.Sprite.Main.Process)]
公共虚拟IEnumerable转换器(PXAdapter)
{
BAccount bacct=this.BAccount.Current;
if(bacct!=null&(bacct.Type==BAccountType.ProspectType | | bacct.Type==BAccountType.CustomerType))
{
保存。按();
AP.VendorMaint editingBO=PXGraph.CreateInstance();
AP.VendorR vendor=(AP.VendorR)editingBO.BAccount.Cache.Extend(bacct);
editingBO.BAccount.Current=供应商;
vendor.Type=(bacct.Type==BAccountType.ProspectType)?BAccountType.VendorType:BAccountType.CombinedType;
LocationExtAddress defflocation=editingBO.defflocation.Select();
editingBO.DefLocation.Cache.RaiseRowSelected(DefLocation);
字符串locationType=(bacct.Type==BAccountType.ProspectType)?LocTypeList.VendorLoc:LocTypeList.CombinedLoc;
编辑bo.InitVendorLocation(解除位置,位置类型);
deffocation=editingBO.deffocation.Update(deffocation);
foreach(editingBO.IntLocations.Select()中的位置iLoc)
{
if(iLoc.LocationID!=defflocation.LocationID)
{
编辑bo.InitVendorLocation(iLoc,locationType);
编辑bo.IntLocations.Update(iLoc);
}
}
编辑bo.Answers.CopyAttributes(供应商、BACT);
抛出新的PXRedirectRequiredException(editingBO,Messages.EditVendor);
}
返回适配器Get();
}
要在同一进程上调用ConverToCustomer和ConverToVendor,需要保持BAccount类的相同实例:
public PXAction<BAccount> converToCustomerThenVendor;
[PXUIField(DisplayName = "Convert To Customer Then Vendor No Redirection", MapEnableRights = PXCacheRights.Select, MapViewRights = PXCacheRights.Select)]
[PXButton(ImageKey = PX.Web.UI.Sprite.Main.Process)]
public virtual IEnumerable ConverToCustomerThenVendor(PXAdapter adapter)
{
//Convert to Customer
try
{
Base.converToCustomer.Press();
}
catch (PXRedirectRequiredException ex)
{
var customerGraph = ex.Graph as CustomerMaint;
//Add your own extended logic here.
//Save the new Customer to the database
customerGraph.Actions.PressSave();
//Set the current instance of BAccount as the one you just saved in the customer graph
Base.BAccount.Current = customerGraph.BAccount.Current;
}
//Convert to vendor
try
{
Base.converToVendor.Press();
}
catch(PXRedirectRequiredException ex)
{
var vendorGraph = ex.Graph as VendorMaint;
//Add your own extended logic here.
//Save the new Vendor to the database
vendorGraph.Actions.PressSave();
//Set the current instance of BAccount as the one you just saved in the vendor graph
Base.BAccount.Current = vendorGraph.BAccount.Current;
}
//Refresh the page with the new data
Base.Actions.PressCancel();
return adapter.Get();
}
public PXAction converToCustomerThenVendor;
[PXUIField(DisplayName=“转换为客户,然后转换为供应商,无重定向”,MapEnableRights=PXCacheRights.Select,MapViewRights=PXCacheRights.Select)]
[PXButton(ImageKey=PX.Web.UI.Sprite.Main.Process)]
公共虚拟IEnumerable ConverToCustomerThenVendor(PXAdapter适配器)
{
//转换为客户
尝试
{
Base.converToCustomer.Press();
}
捕获(PXREQUIREDEXCEPTION ex)
{
var customerGraph=如customerMain所示的图表;
//在这里添加您自己的扩展逻辑。
//将新客户保存到数据库中
customerGraph.Actions.PressSave();
//将BAccount的当前实例设置为刚刚保存在客户图中的实例
Base.BAccount.Current=customerGraph.BAccount.Current;
}
//转换为供应商
尝试
{
Base.converToVendor.Press();
}
捕获(PXREQUIREDEXCEPTION ex)
{
var vendorGraph=以VendorMain表示的图形;
//在这里添加您自己的扩展逻辑。
//将新供应商保存到数据库中
操作。按Save();
//将BAccount的当前实例设置为刚刚保存在供应商图中的实例
Base.BAccount.Current=vendorGraph.BAccount.Current;
}
//用新数据刷新页面
Base.Actions.PressCancel();
返回适配器Get();
}
请提供您的代码,以便进一步理解。您所说的“为同一客户添加供应商记录”是什么意思。如果您试图添加与客户ID相同的供应商,我认为这是不可能的。由于acumatica给出错误“此ID已用于其他供应商或客户记录”。客户和供应商在数据库中共享相同的BAccount记录。所以BAccount记录已经存在,我只是更新它并添加一个供应商记录。我的代码是有效的,但当我在同一个过程中更新客户端,然后更新供应商端时,它就不起作用了。谢谢,是的,这很有意义。当我在客户屏幕之外的流程中添加组合类型记录时,我正在尝试添加该记录。如何通过customerMaint图的实例访问converToVendor的这些操作?customerMaint中有一个类似的操作,名为ExtendToVendor/ExtendToVendor