普通的setDataListBykey 和getDataListByKey接口已经满足KV数据的绝大多数存取需求,但是当需要实现全服共同宗门系统(全局属性,例如总人数和贡献值等)、全服共同拍卖行(售卖物品的剩余数量)等大型跨游戏房间功能的时候,容易出现数据的彼此覆盖,没法保证全局唯一性。
为保证全局唯一性,我们特意设计了全新的UpdateDataListByKey接口。使用该接口,开发者仅需自己处理一个回调函数,在函数中处理自己的数据的逻辑。接口底层会自动重试,直至数据修改成功。
注意:此接口只在云服有效,不要单机或联机测试这个接口!
注意:此接口只在云服有效,不要单机或联机测试这个接口!!
注意:此接口只在云服有效,不要单机或联机测试这个接口!!!
若遇到冲突、失败的情况,接口会自动回传最新的数据值,并调用开发者的回调函数,按照开发者自己设定的逻辑进行更新数据,确保了数据不出错,不会被其他玩家覆盖。
callback函数示例说明
-- ret只有0和2两种值
-- callback至少会调用两次,首次调用ret必然为0,用于设置数值
-- 第2次或第2次以上调用callback时,如果设置失败会再次调用callback,此时ret为0;如果设置成功则ret为2,不会再次设置
local callback = function (ret,key,value)
-- ret为0时,表示首次写入或者本次写入失败,可能有其他房间在本次写入之前已经写入过数据,需要基于最新值重新计算再次写入,value为数据库中最新值
if ret == 0 then
print("有冲突,这是数据库里最新的值" , value)
--逻辑处理,开发者可根据自己的逻辑,进行增加/减少相应的数值。如实例中是,值+1,则每次都累加1,获取到服务器中最新的值,进行+1
value = value + 1
--返回给底层重试写入
return value
-- ret为2时,说明更新成功,不用做任何操作,callback函数执行结束
elseif ret == 2 then
print("成功,更新后的值 " , value)
end
end
local ret = CloudSever:UpdateDataListByKey('list','score',callback)
if ret == ErrorCode.OK then
end
普通KV存储 VS 全局KV数据并发读写
普通KV存储set操作时,执行速度更快一些。直接保存key对应的数据,只会有写入时的每分钟请求次数限制。但是在多服同时对同一个KEY进行写数据的时候容易造成数据不一致。
全局KV数据并发读写(UpdateDataListByKey)执行更慢,因为修改之前会读取最新的值,然后尝试写入。因此该接口同时受到读取和写入的每分钟请求次数限制。另外,它第一次操作某个key时,因为数据不存在会返回空值,此时依然是在callback里面处理,并提交首次有效数据给底层。
注意事项
1.UpdateDataListByKey接口无需事先设置key对应的数据,因为数据都在callback里面提交,从无到有的第一次数据也是这里提交。这样才能避免同时对同一个KEY的数据操作时,彼此冲突覆盖问题;
2.非必要慎用UpdateDataListByKey接口,性能降低。只有业务场景,必须要对同一个key的数据进行写操作时,保证唯一性、正确性的场景和功能时,才推荐使用该接口;
3.使用UpdateDataListByKey修改过的数据,请勿使用普通setDataListBykey接口去设置新值,因为会直接覆盖掉原来数据,没法保证唯一、正确性,而且有可能导致其它问题;
4.对同一个key,禁止混用普通setDataListBykey和UpdateDataListByKey去存数据;
5.此接口只在云服有效,不要单机或联机测试这个接口;
6.每个key只能设置一个回调,设置后不能随意修改;
7.新接口全程无缓存,Update提交的数据不能用CloudSever:getlistCache()获取,直接用getDataListByKey()获取当前最新的数据;
8.Update接口操作的数据,其set操作只能在callback里面,并采用返回最新value进行修改,千万别基于自己调用get拿到的数据进行操作,容易导致数据覆盖,出错。