In Database has a table named SystemSequences in Axapta 3. It saved RecId for each company two types:TransId, SEQNO and likes NS
In Dynamics AX, recId is assigned according to the nextVal (ID -1, name SEQNO) of SystemSequence table. But the next value of RecId is not always retrieved from the table, and it is cached in client machine's memory. In AX3.0, the default cache size is 25.
Developers can change the default cache size using SystemSequence class:
In the startupPost method of Application class, you can add the following code:
Developers can change the default cache size using SystemSequence class:
In the startupPost method of Application class, you can add the following code:
SystemSequence SystemSequence;
…
…
SystemSequence = new SystemSequence();
SystemSequence.setCacheSize(30);
SystemSequence.setCacheSize(30);
As a result, recIDs are drawn in sets of 30. That also means that the next value of SystemSequence table will be increased by 30 each time.
In AX 4.0, recIds will be generated unique per table instead of per company.
So for each table, there will be a nextVal (ID -1, name SEQNO) in SystemSequence table. The cache size for recId allocation is increased to 250. And AX 4 does not allow changing cache size for recId allocation anymore.
以下是转贴:
1,RECID 保存在表systemSequences的字段NextVal里,ID=-1.每个公司一条记录。
2,RECID在保存数据的时候由Axapta的内核类XRecord自动产生(XRecord同时还产生系统字段,比如修改人,修改日期等),为了保证数据库不因为RECID而死锁又能回滚数据,XRecord往往使用一个而外的连接来操作数据;
3,RECID是有系统的内核产生的,下一位未必就是这个值加1。我们不要试图去修改和引用这个数据,由系统自己维护, 但是假如我们一定要强制分配特殊的RECID值的话,我们可以通过调用class SystemSequences来实现。参考例子:
YouTable YT;
SystemSequences obj;
;
obj = new SystemSequences();
obj.SuspendRecIDs(tablenum(YT));
YT.overwriteSystemFields(TRUE);
YT.clear();
YT.RecID = 4711;
...
YT.insert;
obj.removeRecIDSuspension(tablenum(YT));
4,假如我们从用其他的语言来插入记录的话,应该使用Axapta的 Com接口来插入,插入时,接口会自动的维护系统字段,更详细的介绍和帮助我们可以参考\BIM目录下的AxDvgCOMUs.chm文档。
5。系统运行太久以后,有很多的RECID已经无用的了,可能时已经删除,或者是跳过,并且RECID会变得很大,这时,我们可以运行AOT/Classes/SysRecidRepair来重新分配和修复RECID。注意:假如你有些表是通过用RECID来标识记录的话,并且扩展类型是RECID的话,系统会自动更新连接,所以,设计时,若你的表要引用RECID的话,需要扩展位REID。否则在重建RECID时将失去连接!但这是一个很消耗时间的行为!
6,另外,我们可以使用RECID来判断记录是否已经存在数据库中,参考下面的例子:
public void write()
{
if (TableName.RecId)
{
needUpdate();
}
else
{
doNeedUpdate();
}
super();
}
经过测试和试验,终于搞懂了recid的内核机制了,分享。。。。。
系统产生RECID的内核机制揭密
系统产生RECID由表SystemSequences控制,但Nextval并一定是下一个RECID的值。下一个RECID的确切的值保存在客户端的缓存里面,每一个客户端登陆时取得NextVal,并增加25作为客户端的缓存,同样的机制为下一个客户端分配缓存值。当客户端用完了自己的缓存值,便又重新得到新的缓存25,依此类推。下面的机制详细的描述RECID的工作过程。
假设表里的RECID是1000(简化后好记,我的试验的RECID很乱,很长,不容易看),
表里的NextVal RECID值 事件
-------- ---------- --------------
1000 1000 (A) 用户A登陆,
+25 nextVal+25
1025 1001 (A) A增加一条记录
1025 1002 (A) A增加一条记录
.
. (知道A用完了25个缓存,再循环取)
1025 1025 (B) B登陆
+25 nextVal+25
1050 1026 (B) B增加一条记录
1050 1027 (B) B增加一条记录
。
。
。。。。。。。。。。类似的循环不断。。。
系统中有一个class来控制所有的RECID,这个类是:
AOT | System Documentation | Classes | SystemSequence
这个类同时也控制了客户端缓存数量,我们可以用函数setCacheSize(int _newSize)修改缓存数,
用getCacheSize()得到缓存数;
用nextVal( [tableId _tableId = 0] )得到下一个RECID值,注意:若缓存用完,会自动重新取得。
我们可以使用下面的job得到RECID的缓存数量:
static void jobGetRecidCacheSize(Args _args)
{
SystemSequence seq = new SystemSequence();
;
print seq.getCacheSize(); pause;
}
2,RECID在保存数据的时候由Axapta的内核类XRecord自动产生(XRecord同时还产生系统字段,比如修改人,修改日期等),为了保证数据库不因为RECID而死锁又能回滚数据,XRecord往往使用一个而外的连接来操作数据;
3,RECID是有系统的内核产生的,下一位未必就是这个值加1。我们不要试图去修改和引用这个数据,由系统自己维护, 但是假如我们一定要强制分配特殊的RECID值的话,我们可以通过调用class SystemSequences来实现。参考例子:
YouTable YT;
SystemSequences obj;
;
obj = new SystemSequences();
obj.SuspendRecIDs(tablenum(YT));
YT.overwriteSystemFields(TRUE);
YT.clear();
YT.RecID = 4711;
...
YT.insert;
obj.removeRecIDSuspension(tablenum(YT));
4,假如我们从用其他的语言来插入记录的话,应该使用Axapta的 Com接口来插入,插入时,接口会自动的维护系统字段,更详细的介绍和帮助我们可以参考\BIM目录下的AxDvgCOMUs.chm文档。
5。系统运行太久以后,有很多的RECID已经无用的了,可能时已经删除,或者是跳过,并且RECID会变得很大,这时,我们可以运行AOT/Classes/SysRecidRepair来重新分配和修复RECID。注意:假如你有些表是通过用RECID来标识记录的话,并且扩展类型是RECID的话,系统会自动更新连接,所以,设计时,若你的表要引用RECID的话,需要扩展位REID。否则在重建RECID时将失去连接!但这是一个很消耗时间的行为!
6,另外,我们可以使用RECID来判断记录是否已经存在数据库中,参考下面的例子:
public void write()
{
if (TableName.RecId)
{
needUpdate();
}
else
{
doNeedUpdate();
}
super();
}
经过测试和试验,终于搞懂了recid的内核机制了,分享。。。。。
系统产生RECID的内核机制揭密
系统产生RECID由表SystemSequences控制,但Nextval并一定是下一个RECID的值。下一个RECID的确切的值保存在客户端的缓存里面,每一个客户端登陆时取得NextVal,并增加25作为客户端的缓存,同样的机制为下一个客户端分配缓存值。当客户端用完了自己的缓存值,便又重新得到新的缓存25,依此类推。下面的机制详细的描述RECID的工作过程。
假设表里的RECID是1000(简化后好记,我的试验的RECID很乱,很长,不容易看),
表里的NextVal RECID值 事件
-------- ---------- --------------
1000 1000 (A) 用户A登陆,
+25 nextVal+25
1025 1001 (A) A增加一条记录
1025 1002 (A) A增加一条记录
.
. (知道A用完了25个缓存,再循环取)
1025 1025 (B) B登陆
+25 nextVal+25
1050 1026 (B) B增加一条记录
1050 1027 (B) B增加一条记录
。
。
。。。。。。。。。。类似的循环不断。。。
系统中有一个class来控制所有的RECID,这个类是:
AOT | System Documentation | Classes | SystemSequence
这个类同时也控制了客户端缓存数量,我们可以用函数setCacheSize(int _newSize)修改缓存数,
用getCacheSize()得到缓存数;
用nextVal( [tableId _tableId = 0] )得到下一个RECID值,注意:若缓存用完,会自动重新取得。
我们可以使用下面的job得到RECID的缓存数量:
static void jobGetRecidCacheSize(Args _args)
{
SystemSequence seq = new SystemSequence();
;
print seq.getCacheSize(); pause;
}