zoukankan      html  css  js  c++  java
  • 第十七章 性能(三)

    本文仅供AX从业者和爱好者讨论学习之用,由于原文版权问题请勿转载并期待您的指正.
    接上文
    这种方式比下面代码显示的一条条记录插入有很大的效率提升,它们达到的效果是一样的
    static void CopySizes(Args _args)
    {
        InventSize inventSizeTo;
        InventSize inventSizeFrom;
        InventTable inventTable;
        ;
        ttsbegin;
        
    while select itemId from inventTable
                where inventTable.ItemId 
    == 'PB-Metal Shade'
            join inventSizeId,description,name from inventSizeFrom
                where inventSizeFrom.ItemId 
    == 'PB-Plastic Shade'
        
    {
            inventSizeTo.ItemId         
    =   inventTable.itemId;
            inventSizeTo.InventSizeId   
    =   inventSizeFrom.InventSizeId;
            inventSizeTo.Description    
    =   inventSizeFrom.Description;
            inventSizeTo.Name           
    =   inventSizeFrom.Name;
            inventSizeTo.insert();
        }

        ttscommit;
     
    }
    如果要拷贝10个大小,这种场景下select语句会跟数据库服务器发生一次交互,insert语句会发生10交互,总共11次交互.
    但是批操作可能会被降级成记录操作(译注:原文是record-base operation,直接翻译是基于记录的操作,感觉有些别扭,这里翻译成记录操作).在满足下面任何一种情况时都会发生降级:
    1.该表是全表缓存的.
    2.目标表的(译注:即要在其中插入记录的表)insert或者aosValidateInsert方法被重载.
    3.设置了在目的表中插入记录时产生预警.
    4.配置了数据库日志以记录目的表的插入动作
    (译注:AX可以通过  系统管理->设置->数据库日志  设置记录某些表的插入或者更改动作,如果在这里设置了,那么在设定了的表发生插入或者更改动作时,AX运行时会把这些信息记录在表SysDataBaseLog中,可以通过 系统管理->查询->数据库日志 查看)
    DynamicsAX应用运行时会自动处理降级,内部执行的过程跟前面提到的while select一样.
    重要   当DynamicsAX应用运行时检测重载方法时,它只关心这些方法是否实现.它不关心这些被重载的方法是否只包含默认的X++代码.因此,即使一个方法只包含如下X++代码,应用运行时也会认为它被重载了:
    public void insert()
    {
        super();
    }
    这样任何批插入操作就被降级了.因此删除这样的方法以避免效率的降低(译注:原文It is important that you delete such a method to avoid the downgrade with its performance ramifications其中ramification是分支,分歧或者后果的意思,结合原文翻译成这几个意思感觉都不太好理解,这里省略了).
    但是除了表采用了全局缓存外,可以避免上面提到的功能引起的任何降级.  记录缓存(译注:原文The record buffer,这个还真不知道怎么翻译,实际上就是表变量,还真整不明白为什么叫buffer) 包含一些方法,这些方法可以关掉运行时执行的决定是否应该将insert_recordset降级的检测.调用skipDataMethods(true)阻止insert是否被重载的检测,调用skipAosValidation(true)阻止检测aosValidateInsert方法.调用skipDatabaseLog(true)阻止检测是否配置了数据库日志来记录该表的插入操作,调用skipEnvents(true)阻止检测是否在该表上设定了由插入事件触发的预警.下面的X++代码包含了对skipDataMethods(true)的调用,因此可以确保insert_recordset不会因为InventSize的insert方法被重载而引起的降级
    static void CopySizes(Args _args)
    {
        InventSize  inventSizeTo;
        InventSize  inventSizeFrom;
        InventTable inventTable;
        ;
        ttsbegin;
        inventSizeTo.skipDataMethods(
    true);
        insert_recordset inventSizeTo(ItemId,InventSizeId,Description,Name)
            select itemId from inventTable
                where inventTable.ItemId 
    == 'PB-Metal Shade'
            join inventSizeId,description,name from inventSizeFrom
                where inventTable.ItemId 
    == 'PB-Plastic Shade';
        ttscommit;

    }
    Skip方法在使用的时候必须特别注意,  避免在Insert中实现X++代码因为将不会被执行,不会被触发的事件,不会被创建的日志,等等。如果重载了insert方法,应该使用交叉应用系统看是否有X++代码调用了skipDataMethods(true),否则X++代码可能会不执行insert方法.另外,当调用skipDataMethods(true)时,确保不执行重载的insert方法中的X++代码不会引起数据的不一致.
    注意skip方法只是用来影响insert_recordset操作是否降级。比如调用skipDataMethods(true)来阻止因为重载了insert方法而引起的降级,如果最终操作被降级了,insert的重载版本仍然会被执行。操作会被降级,比如,如果配置了数据库日志来记录表的插入记录。在前面的例子中,如果配置了数据库日志记录表InventSize的插入操作表InventSize的重载版本的insert方法将会被调用,因为insert_recordSet操作会被转换成while select,在这种情况下重载版本的insert方法会被调用。
    update_recordset 操作符
    update _recordset操作符与 insert_recordset操作符的表现类似。下面的X++代码证明了这一点,该语句将一个产品的所有尺寸用一个新的描述信息更新.
    static void UpdateSizes(Args _args)
    {
        InventSize inventSize;
        ;
        ttsbegin;
        update_recordset inventSize
            setting Description 
    = 'This Size for item PB-Metal Shade'
            where inventSize.ItemId 
    == 'PB-Metal Shade';
        ttscommit;

    }
    update_recordset 操作的执行将提交给数据库服务器一条语句,在SQL Server2000中这条语句的语法类似于UPDATE <table><SET><field and expression list> WHERE <preedicates>.与Insert_recordSe一样,该操作比起记录级操作需要一条条单独更新效率有了很大的提升。下面的X++代码展示了记录级操作,它所实现的功能跟前面的例子是一样的。这段代码首先选出所有满足条件的记录,设定新的描述信息,最后更新记录。
    static void UpdateSizes(Args _args)
    {
        InventSize inventSize;
        ;
        ttsbegin;
        
    while select forupdate inventSize
            where inventSize.ItemId 
    == 'PB-Metal Shade'
            
    {
                inventSIze.Description 
    = 'This size is for item PB-Metal Shade';
                inventSize.update();
            }

        ttscommit;

    }
    如果有10条记录满足条件,那么一条select语句和10条更新语句将会提交给数据库服务器,而update_recordSet只需要一条update语句。
    如果特定的方法被重载或者DynamicsAX应用的设定,update_recordset操作也会被降级。满足如下条件中的一个就会引起降级:
    1.表应用了全表缓存。
    2.目的表的update,aosValidateUpdate或者aosValidateRead方法被重载。
    3.在目的表上设定有由更新查询出发的预警规则。
    4.在数据库日志中配置了记录目的表的更新查询。
    DynamicsAX运行时会自动处理降级,在内部的执行情况跟前面举的例子中的while select 一样。
    (译注:我测试的结果是作者举的例子中update_recordset并不能成功降级成while select语句完成更新,具体描述请参照本文)。
    前面功能应起的降级是可以避免的,除非采用了全表缓存.记录缓存(译注:表变量)包含关闭检测的方法,这些检测由应用运行时执行的用于决定update_recordset操作是否应该被降级的.调用skipDataMethod(true)阻止检测update是否被重载,调用skipAosValidation(true)阻止检测aosValidateUpdate和aosValidateRead方法。调用skipDatabaseLog(true)阻止检测数据库日志是否配置用来记录该表的更新操作,调用skipEvents(true)阻止检测是否在该表上配置了由更新事件触发的预警。
    正如前面提到的那样,在结合update_recordset是用skip方法的时候要特别小心并采取相应的预防措施。同样,skip方法只会影响update_recordset操作是否降级成while select,如果操作最终降级了,数据库日志,预警和被重载方法的执行都会发生,尽管各自的skip方法被调用。
    技巧:如果update_recordset操作被降级成while select ,select语句使用在表上指定的并发模型。可以在update_recordset语句上应用optimisticlock和pessimisticlock来强制被降级后的操作采用指定的并发模型。
    delete_from操作符
    delete_from与insert_recordset和update_recordset操作符类似,可以向数据库提交一个条语句完成多条记录的删除。下面的X++代码删除了一个产品的所有的尺寸。
    static void DeleteSizes(Args _args)
    {
        InventSize inventSize;
        ;
        ttsbegin;
            delete_from inventSize
                where inventSize.ItemId 
    == 'PB-Metal Shade';
        ttscommit;
     
    }

    这段代码提交给SQL Server2000语法类似于DELETE <table> WHERE <predicates>,执行的结果跟通过如下X++代码逐条删除一样。

    static void DeleteSizes(Args _args)
    {
        InventSize inventSize;
        ;
        ttsbegin;
        
    while select forupdate inventSize
            where inventSize.ItemId 
    == 'PB-Metal Shade'
        
    {
            inventSize.delete();
        }

        ttscommit;
    }

    同样,由于只向数据库提交一条语句,比起逐条删除使用delete_from有很大的效率提升。
    与insert_recordset和update_recordset类似,delete_from会因为类似的原因降级。如果满足如下条件中的一个则会发生降级:
    1.表是全表缓存的;
    2.目的表的delete,aosValidateDelete或者aosValidateRead方法被重载;
    3.在目的表上配置了由删除触发的预警;
    4.配置了数据库日志用于记录目的表的删除操作。
    如果在表上定义了delete actions也会发生降级。DynamicsAX应用运行时会自动处理降级在内部执行与前面提到的while select 同样的操作。
    可以避免由前面提到的功能引起的降级,除非采用了全表缓存。记录缓存(译注:表变量)包含关闭检测的方法,这些检测由应用运行时执行的用于决定delete_from操作是否应该被降级的.调用skipDataMethod(true)阻止检测update是否被重载,调用skipAosValidation(true)阻止检测aosValidateDelete和aosValidateRead方法。调用skipDatabaseLog(true)阻止检测数据库日志是否配置用来记录该表的删除操作,调用skipEvents(true)阻止检测是否在该表上配置了由删除事件触发的预警。调用skipDeleteActions(true)阻止检测是否在目的表的元数据上定义了delete actions。
    正如前面提到的skip方法使用的描述,在降级发生的时候,对应的行为并不会被跳过(译注:原文可能是为了避免重复的语句太多换了个说法,作者想表达的意思跟前面是一样的),delete_from也可以使用update_recordset使用的并发模型。
    注释:记录缓存(译注:表变量)也包含skipDeleteMethod方法。调用该方法跟调用skipDataMethods(true)方法的效果是一样的。它实际上触发了同样的DynamicsAX应用运行时逻辑,所以可以结合insert_recordset和update_recordset使用skipDeleteMethod方法,尽管这并不会提高X++代码的可读性(译注:那何必要加这么个方法那?)

  • 相关阅读:
    UIVIew详解
    UIView对象转成UIImage对象
    OC 获取IOS屏幕尺寸大小
    presentModalViewController和dismissModalViewControllerAnimated的替代方法
    设计模式之观察者模式(关于OC中的KVO(Observer)KVCNSNotification)
    Key-Value Observing机制
    iOS对象序列化与反序列化( NScoder 和 NScoding )
    IOS 关键字self,super,copy, retain, assign , readonly , readwrite, nonatomic、@synthesize、@property、@dynamic
    UIImage 缩放
    CentOS6.8下二进制安装mysql5.7
  • 原文地址:https://www.cnblogs.com/Farseer1215/p/731578.html
Copyright © 2011-2022 走看看