“LlUpdateKeyValue”的版本间的差异
(创建页面,内容为“{{LSL Header|ml=*}}{{LSLC|Keywords}}{{LSLC|Flow Control}}{{LSLC|}} {{函数详情 |函数名 = Function: key llUpdateKeyValue( string k, string v, integer checked,…”) |
|||
第73行: | 第73行: | ||
} | } | ||
} | } | ||
− | + | </pre> | |
+ | 这个脚本演示了如何避免更新冲突(两个脚本同时更新存储),执行完全原子更新更为复杂。如果所有写入键值存储区的脚本都遵守虚拟锁($DB_lock),并且只在update_DB状态下进行更新,则所有写入都将是原子的。 | ||
key tid; | key tid; | ||
第163行: | 第164行: | ||
</pre> | </pre> | ||
+ | <pre> | ||
|相关函数= | |相关函数= | ||
[[llGetExperienceErrorMessage]] | [[llGetExperienceErrorMessage]] |
2020年9月9日 (三) 11:16的版本
首页 | 函数 | 事件 | 类型 | 操作符 | 常数 | Flow Control | Script Library | Categorized Library | Tutorials |
函数名 |
---|
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 |
相关事件 |
---|
无 |