“LlUpdateKeyValue”的版本间的差异

来自人工智能助力教育知识百科
跳转至: 导航搜索
Wzc讨论 | 贡献
 
第74行: 第74行:
 
}
 
}
 
</pre>
 
</pre>
 +
 +
<pre>
 
这个脚本演示了如何避免更新冲突(两个脚本同时更新存储),执行完全原子更新更为复杂。如果所有写入键值存储区的脚本都遵守虚拟锁($DB_lock),并且只在update_DB状态下进行更新,则所有写入都将是原子的。
 
这个脚本演示了如何避免更新冲突(两个脚本同时更新存储),执行完全原子更新更为复杂。如果所有写入键值存储区的脚本都遵守虚拟锁($DB_lock),并且只在update_DB状态下进行更新,则所有写入都将是原子的。
  
第164行: 第166行:
 
</pre>
 
</pre>
  
<pre>
+
 
 
|相关函数=
 
|相关函数=
 +
 
[[llGetExperienceErrorMessage]]  
 
[[llGetExperienceErrorMessage]]  
  

2020年9月9日 (三) 11:17的最新版本

Template:Needs Translation/


函数名
Function: key llUpdateKeyValue( string k, string v, integer checked, string original_value );
参数:•字符串k(string k)–键值对的键

•字符串v(string v)–键值对的值。最多2047个字符,如果使用单声道,则为4095个字符。

•整数已检查(integer checked)–如果为真,则只有原始_值与键值存储区中的值匹配时才会进行更新。

•字符串原始值(string original_value)–要与键值存储区中的当前值进行比较的值。

如果checked设置为TRUE,则只有当原始值与键值存储区中的当前值匹配时,才会进行更新,否则数据服务器将返回失败,并返回错误XP_error_RETRY_update。这可以用来创建一个正在使用的标志,这样就可以实现原子性。

返回值:返回一个句柄(键),该句柄可用于标识相应的数据服务器事件,以确定此命令是成功还是失败以及结果。

截至2016年1月1日,LSO和Mono脚本的最大字节数分别为1011和4095。

使用llUpdateKeyValue更新不存在的密钥将不会生成XP\u ERROR\u key unt\u FOUND。相反,它将生成一个具有指定值的新键,就像您使用了llCreateKeyValue一样。

要使此功能正常工作,必须将脚本编译为一个体验Experience

注意事项
数据服务器回调参数为:

包含从llUpdateKeyValue返回的句柄的键 包含逗号分隔列表(cdl)的字符串。llDumpList2String([integer success]+组件); 组件根据请求的成功或失败而变化。 失败:cdl=llDumpList2String([0,整数错误],“,”) 成功:cdl=llDumpList2String([1,字符串值],“,”) 字符串组件

•整数成功–一个布尔值,指定事务是否成功(1)或否(0)。

•整数错误–描述操作失败原因的XP_error_x标志。

•字符串值–键值对的值。最多2047个字符,如果使用单声道,则为4095个字符。注意!此值可能包含逗号。

如果重新编译以前与体验相关联的脚本,但对缺乏将脚本编译为体验能力的客户端执行此操作,则该脚本将丢失关联的体验。 由于llKeysKeyValue以CSV格式返回密钥,建议密钥不包含逗号。

示例
示例1
key trans;
default
{
    state_entry()
    {
        trans = llUpdateKeyValue("FOO", "BLAH", TRUE, "BAR");
    }
 
    dataserver(key t, string value)
    {
        if (t == trans)
        {
            // our llUpdateKeyValue transaction is done
            list result = llCSV2List(value);
            if (llList2Integer(result, 0) == 1)
            {
                // the key-value pair was successfully updated
                llSay(0, "New key-value pair was successfully updated");
            }
            else
            {
                integer error = llList2Integer(result, 1);
                if(error == XP_ERROR_RETRY_UPDATE)
                    llSay(0, "Key-value update failed, checked value is out of date");
                else
                    llSay(0, "Key-value update failed: " + llGetExperienceErrorMessage(error) );
            }  
        }
    }
}
这个脚本演示了如何避免更新冲突(两个脚本同时更新存储),执行完全原子更新更为复杂。如果所有写入键值存储区的脚本都遵守虚拟锁($DB_lock),并且只在update_DB状态下进行更新,则所有写入都将是原子的。

key tid;
list tids;
 
default {
    state_entry() {
        state lock_db;
    }
}
 
state lock_db {
    state_entry() {
        tid = llUpdateKeyValue("$DB_Lock", "LOCK", TRUE, "unlock");
    }
    dataserver(key did, string value) {
        if(did == tid) {
            string payload = llDeleteSubString(value, 0, 1);
            if(llGetSubString(value+",", 0, 1) == "1,"){
                llUpdateKeyValue("$DB_LockedBy", llDumpList2String([llGetOwner(),llGetKey(),llGetLinkKey(!!llGetLinkNumber()),llGetRegionName(),llGetPos(),llGetAttached()],":"), FALSE, "");
                state update_db;
            } else {
                integer err = (integer)payload;
                if(err == XP_ERROR_RETRY_UPDATE) {
                    llSay(0, "Database is already locked!");
                } else {
                    llSay(0, "Key-value update failed: " + llGetExperienceErrorMessage(err) );
                }
                state error;
            }
        }
    }
}
 
state update_db {
    state_entry() {
        tids = [
            llUpdateKeyValue("CatsPermissable", "5", FALSE, ""),
            llUpdateKeyValue("MonkeyMutations", "3", FALSE, ""),
            llUpdateKeyValue("CodFlavorSupport", "NEVER", FALSE, "")
        ];
    }
    dataserver(key did, string value) {
        integer i = llListFindList(tid, [did]);
        if(~i) {
            string payload = llDeleteSubString(value, 0, 1);
            if(llGetSubString(value+",", 0, 1) == "1,"){
                tids = llDeleteSubList(tids, i, i);
                if(tids == []) {
                    state unlock_db;
                }
            } else {
                llSay(0, "Key-value update failed: " + llGetExperienceErrorMessage((integer)payload) );
                state error;
            }
        }
    }
}
 
state unlock_db {
    state_entry() {
        tid = llUpdateKeyValue("$DB_Lock", "unlock", TRUE, "LOCK");
    }
    dataserver(key did, string value) {
        if(did == tid) {
            string payload = llDeleteSubString(value, 0, 1);
            if(llGetSubString(value+",", 0, 1) == "1,"){
                state done;
            } else {
                integer err = (integer)payload;
                if(err == XP_ERROR_RETRY_UPDATE) {
                    llSay(0, "Someone has violated the database lock!");
                } else {
                    llSay(0, "Key-value update failed: " + llGetExperienceErrorMessage(err) );
                }
                state error;
            }
        }
    }
}
 
state done {
    state_entry(){;}
}
 
state error {
    state_entry(){;}
}
相关函数
llGetExperienceErrorMessage

llCreateKeyValue

llReadKeyValue

llUpdateKeyValue

llDeleteKeyValue

llDataSizeKeyValue

llKeyCountKeyValue

llKeysKeyValue

相关事件