• AX TTS总结


    AX的事物管理通过关键字ttsbegin/ttscommit/ttsabort来处理用一个事务要不全做要不全不做

    常用的写法有:

     1 try
     2 {
     3   ttsbegin;
     4   //do something1
     5   //do something2
     6   ttscommit;
     7 }
     8 catch
     9 {
    10   ttsabort;
    11 }

    这里do something1do something2,要不全做其中有一个出现问题,则两个都不做

    另外使用tts,还有下面一些小细节:

    (1)ttsabort不会马上终止程序,而是继续运行后面与transaction无关的statements (best practise建议使用throw exception而取代ttsabort)。

    (2)嵌套tts,直到最外层的ttscommit运行后,数据才真正更新到数据库中。

    (3)系统内置有一个叫ttslevel的变量,默认是0。每次ttsbegin,ttslevel就加1,每次ttscommit,ttslevel就减1,而ttsabort会直接把ttslevel清0。也就是0这个状态才代表整个transaction运行完事。当使用ax的form保存数据的时候,系统会首先检测ttslevel(比validateWrite更早,在form的task的super里头运行),如果ttslevel不为0,就会提示以下错误,导致更新终止。

    (我们可以使用new xApplication().ttslevel()来查看当前的ttslevel)

    看些例子:

    例1

    1           //Default at the beginning TTSLEVEL = 0                                                          
    2 TTSBEGIN;       //TTSLEVEL = 1                                               
    3 //Do something
    4 TTSBEGIN;       //TTSLEVEL = 2
    5 //Do something
    6 TTSCOMMIT;       //TTSLEVEL = 1
    7 //Do something
    8 TTSCOMMIT;        //TTSLEVEL = 0.                                             

    例2

     1                //Default at the beginningTTSLEVEL = 0
     2 TTSBEGIN;          //TTSLEVEL = 1
     3 //Do something
     4 try
     5 {
     6   TTSBEGIN;        //TTSLEVEL = 2
     7    //Do something
     8    TTSCOMMIT;             //TTSLEVEL = 1 (没错误情况)
     9 }
    10 catch
    11 {
    12   TTSABORT;             //TTSLEVEL = 0 (有错误情况)
    13     //Do something
    14 }
    15 TTSCOMMIT;               //TTSLEVEL = 0 (没错误情况),
    16                //TTSLEVEL = -1 (有错误情况), 这个绝对不是我们想要得到的结果.所以结合第一点,我们应尽量避免使用ttsabort

    (4)ttsbeginttscommit中间的程序在最外层ttscommit之前是不会更新数据库的但如果通过AX代码更新数据在没有commit之前依然能获取transaction前半段插入的数据

    试试下面例子:

     1 static void testTTS(Args _args)
     2 {
     3   VendTable vendTable, vendTable2;
     4   ;
     5 
     6   ttsbegin;
     7   vendTable.clear();
     8   vendTable.AccountNum = 'TestingTTS';
     9   vendTable.doInsert();
    10   select vendTable2
    11     where vendTable2.AccountNum == 'TestingTTS';
    12 
    13   print vendTable2.AccountNum;
    14   //取得记录
    15 
    16   vendTable2 = VendTable::find('TestingTTS');
    17 
    18   print vendTable2.AccountNum;
    19   //取得记录
    20 
    21   pause;
    22 
    23   delete_from vendTable
    24     where vendTable.AccountNum == 'TestingTTS';
    25   ttscommit;
    26 }

    所以我们有理由怀疑AX会合并内存和数据库中的内容,便于我们编程。但是如果通过外部程序直接查询数据库,那在commit之前是不能读出那些在transaction中途插入或修改的数据的(有个具体例子是,我们使用Table来保存一些打印数据,然后调用外部水晶报表程序来打印报表。该水晶报表直接读取AX数据库,所以他打印报表那句必须在commit之后调用,否则不能读出相应数据)

    (5)ttsbegin/ttscommit/ttsabort针对写入数据库的事务管理。那么对于只更新内存的临时表的写入,它们是不起作用的。对于临时表,我们需要使用

      临时表变量.ttsbegin();

      临时表变量.ttscommit();

      临时表变量.ttsabort();

    (6)update_recordset,delete_from,insert_recordset那些语句是单条SQL命令,无需事务控制。

     

      感谢秋毫的fat0527总结。

     

     

  • 相关阅读:
    LinqToSQL4
    java 连接数据库操作
    javadoc生成文档报错 java.lang.IllegalArgumentException
    maven下载依赖jar包,Could not transfer artifact xxxxx
    关于meaven导入依赖出现Failed to read artifact descriptor for ***包
    mybatis-plus项目自动生成代码
    Spring boot 出现 "org.springframework.beans.factory.UnsatisfiedDependencyException" 错误
    vs 调试显示用户关闭隐式函数计算
    vue api排放顺序及属性,用于理解vue
    vue 拦截器
  • 原文地址:https://www.cnblogs.com/Jinnchu/p/2658860.html
Copyright © 2020-2023  润新知