加锁方法和装置与流程

文档序号:12465121阅读:389来源:国知局
加锁方法和装置与流程

本公开涉及数据处理技术领域,尤其涉及一种加锁方法和装置。



背景技术:

当不同系统或者同一个系统的不同主机之间共享了某数据时,可能会出现上述不同的系统或者主机同时访问该数据造成数据不一致的问题,为了解决上述问题,需要对数据加锁,该锁的作用是当某主机访问该数据时拒绝另一主机对该数据进行操作。

当数据已被一个主机加锁时,其他主机需要等待锁超时才能抢锁,例如一种加锁方法采用如下方式完成上述过程:获取锁的值,然后判断锁是否超时,如果锁超时则进行抢锁操作。

在上述过程中,可能在获取锁的值之前,该锁已经被其他主机抢到并删除,此时判断锁是否超时会报空指针异常,造成不必要的时间和空间的浪费。



技术实现要素:

为克服相关技术中存在的问题,本公开提供一种加锁方法和装置。

根据本公开实施例的第一方面,提供一种加锁方法,所述方法包括:

获取数据库中目标对象的锁的值;

判断是否获取到所述目标对象的锁的值;

当获取到所述目标对象的锁的值时,根据所述目标对象的锁的值判断所述目标对象的锁是否超时;

当所述目标对象的锁超时时,对所述目标对象重新加锁。

本公开通过在判断所述目标对象的锁是否超时之前,执行判断是否获取到所述目标对象的锁的值的操作,避免锁已经被其他主机抢到并删除时仍然判断锁是否超时出现的空指针异常,减少不必要的时间和空间的浪费去处理不能执行完的业务,使得业务逻辑执行的更加完整。

在本公开的一种实现方式中,所述获取数据库中目标对象的锁的值,包括:

采用SETNX命令对所述目标对象进行加锁操作;

在对所述目标对象加锁失败时,通过GET命令获取所述目标对象的锁的值。

在该实现方式中,获取目标对象的值是在采用SETNX命令加锁操作失败时进行的,当采用SETNX命令加锁操作失败,表明此时目标对象已被加锁,采用GET命令获取数据库中目标对象的锁的值,确定是否超时,从而执行后续操作。

在本公开的另一种实现方式中,所述方法还包括:

获取采用所述SETNX命令对所述目标对象进行加锁操作的返回值;

根据所述返回值,确定对所述目标对象加锁是否成功。

在该实现方式中,通过采用SETNX命令进行加锁操作得到返回值判断,加锁是否成功,简单准确,为后续步骤提供执行依据。

在本公开的另一种实现方式中,所述对所述目标对象重新加锁,包括:

对所述目标对象执行GETSET命令,所述GETSET命令用于获取所述目标对象的锁的值,并在未获取到所述目标对象的锁的值或者所述目标对象的锁超时时,完成对所述目标对象的加锁操作。

在该实现方式中,在执行GETSET命令时,同样增加判断是否获取到所述目标对象的锁的值的操作,避免空指针异常报错。

在本公开的另一种实现方式中,所述方法还包括:

当未获取到所述目标对象的锁的值时,或者当所述目标对象的锁未超时时,在设定时间内进行休眠,并在休眠后重新获取所述目标对象的锁的值。

在该实现方式中,当目标对象字的锁未超时,进行休眠操作,避免对目标对象重复加锁。

在本公开的另一种实现方式中,所述方法还包括:

当对所述目标对象重新加锁后,监督在所述目标对象的锁超时之后,所述目标对象的锁是否被改动;如果在所述目标对象的锁超时之后,所述目标对象的锁没有被改动,则删除所述目标对象的锁。

在删除锁时,通过判断在判断出目标对象的锁超时之后,目标对象的锁没有被改动,避免锁被其他主机获取时产生的误删除操作。

根据本公开实施例的第二方面,提供一种加锁装置,所述装置包括:

获取模块,用于获取数据库中目标对象的锁的值;

判断模块,用于判断是否获取到所述目标对象的锁的值;

处理模块,用于当获取到所述目标对象的锁的值时,根据所述目标对象的锁的值判断所述目标对象的锁是否超时;

当所述目标对象的锁超时时,对所述目标对象重新加锁。

在本公开的一种实现方式中,所述获取模块,用于:

采用SETNX命令对所述目标对象进行加锁操作;

在对所述目标对象加锁失败时,通过GET命令获取所述目标对象的锁的值。

在本公开的另一种实现方式中,所述处理模块,还用于:

获取采用所述SETNX命令对所述目标对象进行加锁操作的返回值;

根据所述返回值,确定对所述目标对象加锁是否成功。

在本公开的另一种实现方式中,所述处理模块,还用于:

对所述目标对象执行GETSET命令,所述GETSET命令用于获取所述目标对象的锁的值,并在未获取到所述目标对象的锁的值或者所述目标对象的锁超时时,完成对所述目标对象的加锁操作。

在本公开的另一种实现方式中,所述处理模块,还用于:

当未获取到所述目标对象的锁的值时,或者当所述目标对象的锁未超时时,在设定时间内进行休眠,并在休眠后重新获取所述目标对象的锁的值。、

在本公开的另一种实现方式中,所述处理模块,还用于:

当对所述目标对象重新加锁后,监督在所述目标对象的锁超时之后,所述目标对象的锁是否被改动;如果在所述目标对象的锁超时之后,所述目标对象的锁没有被改动,则删除所述目标对象的锁。

根据本公开实施例的第三方面,提供一种加锁装置,所述装置包括:

处理器;

用于存储处理器可执行指令的存储器;

其中,所述处理器被配置为:

获取数据库中目标对象的锁的值;

判断是否获取到所述目标对象的锁的值;

当获取到所述目标对象的锁的值时,根据所述目标对象的锁的值判断所述目标对象的锁是否超时;

当所述目标对象的锁超时时,对所述目标对象重新加锁。

本公开的实施例提供的技术方案可以包括以下有益效果:

本公开通过在判断所述目标对象的锁是否超时之前,执行判断是否获取到所述目标对象的锁的值的操作,避免锁已经被其他主机抢到并删除时仍然判断锁是否超时出现的空指针异常,减少不必要的时间和空间的浪费去处理不能执行完的业务,使得业务逻辑执行的更加完整。

应当理解的是,以上的一般描述和后文的细节描述仅是示例性和解释性的,并不能限制本公开。

附图说明

此处的附图被并入说明书中并构成本说明书的一部分,示出了符合本发明的实施例,并与说明书一起用于解释本发明的原理。

图1是根据一示例性实施例示出的应用场景图。

图2是根据一示例性实施例示出的一种加锁方法的流程图。

图3是根据一示例性实施例示出的一种加锁方法的流程图。

图4是根据一示例性实施例示出的一种加锁装置的框图。

图5是根据一示例性实施例示出的一种加锁装置的框图。

具体实施方式

这里将详细地对示例性实施例进行说明,其示例表示在附图中。下面的描述涉及附图时,除非另有表示,不同附图中的相同数字表示相同或相似的要素。以下示例性实施例中所描述的实施方式并不代表与本发明相一致的所有实施方式。相反,它们仅是与如所附权利要求书中所详述的、本发明的一些方面相一致的装置和方法的例子。

为了便于实施例的描述,下面先简单介绍一下本公开中实施例的应用场景。图1是根据一示例性实施例示出的应用场景图,参见图1,该场景中网络架构包括:数据库层100、缓存层200、多个逻辑服务器300和多个客户端400。每个逻辑服务器300可以连接多个客户端400,多个逻辑服务器300同时对缓存层200中的数据进行操作,缓存层200中的数据可以定时同步到数据库层100中。为了避免保持数据的一致性,需要对数据设置锁。即一个逻辑服务器300可以通过对数据加锁来保证该数据不被其他逻辑服务器操作。

其中,缓存层200可以使用Redis(英文REmote DIctionary Server)技术作为数据中间层,与数据库层100形成主从库分布,数据库层100作永久存储。其中,缓存层200和数据库层100可以为互相隔离的服务器。Redis技术采用Key-Value实现数据存储。

逻辑服务器300可以与客户端400进行数据交互,接收客户端400发送的业务请求,根据业务请求执行相应地业务逻辑,在执行业务逻辑时,对缓存层200中的数据进行操作。例如,在电商系统中,客户端400请求发货时,则逻辑服务器300执行发货逻辑,执行发货逻辑时,逻辑服务器300会对缓存层200中的货物数量进行修改(数量减1)。而在执行上述业务逻辑前,逻辑服务器300必须要获得对相应数据进行操作的权限,为了获得该权限就要执行相应地加锁过程,该过程由逻辑服务器300执行,在接收到客户端400发起的业务请求后,逻辑服务器300根据业务请求对相应地数据进行加锁,以获取权限,具体见本公开后文描述。

需要说明的是,以上所述的设备种类仅为举例,本公开对此不作限制。

图2是根据一示例性实施例示出的一种加锁方法的流程图,该方法基于Redis技术实现,如图2所示,该加锁方法适用于前述场景中的逻辑服务器,包括以下步骤:

在步骤S11中,获取数据库中目标对象的锁的值。

其中,目标对象为关键字。在缓存层和数据库层等数据库中数据通常采用关键字-值(Key-Value)的方式进行存储,其中关键字可以是名称、编号等。以前述货物数量为例,关键字为数量,值为5。

目标对象的锁用于限定目标对象对应的数据的访问权限,该锁可以包括两个部分,例如键和值,键是一个标识(例如可以采用发送请求的客户端的标识),值通常为超时时间。

在步骤S12中,判断是否获取到目标对象的锁的值。

即判断获取到的目标对象的锁的值是否为空(null),若获取到的目标对象的锁的值为空则表示未获取到目标对象的锁的值,若获取到的目标对象的锁的值不为空则表示获取到目标对象的锁的值。

在步骤S13中,当获取到目标对象的锁的值时,根据目标对象的锁的值判断目标对象的锁是否超时。

目标对象的锁的值可以为Unix时间戳,此时,判断目标对象的锁是否超时可以包括:将Unix时间戳转换为对应的超时时间(例如北京时间),判断当前时间是否超过其对应的超时时间,若当前时间超过超时时间则说明目标对象的锁超时,当前时间未超过超时时间,则说明目标对象的锁未超时。当前时间可以由逻辑服务器从本地或者网络获取到。例如,获取到的Unix时间戳为1472968681,则其对应的北京时间为2016/9/4 13:58:01,若当前时间为2016/9/4 15:00:00,则说明该目标对象的锁超时。

进一步地,当未获取到目标对象的锁的值时,在设定时间内进行休眠,并在休眠后重新获取数据库中目标对象的锁的值。

在步骤S14中,当目标对象的锁超时时,对目标对象重新加锁。

其中,对目标对象重新加锁后,该目标对象的锁的键与本逻辑服务器对应,而对目标对象重新加锁前,该目标对象的锁的键与其他逻辑服务器对应。

对目标对象加锁,可以防止目标对象对应的数据被其他逻辑服务器修改。

本公开通过在判断目标对象的锁是否超时之前,执行判断是否获取到目标对象的锁的值的操作,避免锁已经被其他主机(如逻辑服务器)抢到并删除时仍然判断锁是否超时出现的空指针异常,减少不必要的时间和空间的浪费,同时这样做可以避免去处理不能执行完的业务,使得业务逻辑执行的更加完整。

在图2示出的方法的基础上,可选地,上述获取数据库中目标对象的锁的值可以包括:

采用SETNX命令对目标对象进行加锁操作;

在对目标对象加锁失败时,通过GET命令获取目标对象的锁的值。

其中,SETNX是SET if Not eXists的简写,意为如果目标对象不存在锁则进行加锁。

可选地,该方法还可以包括:

获取采用SETNX命令对目标对象进行加锁操作的返回值;

根据返回值,确定对目标对象加锁是否加锁。

例如返回值可以为1或0,1表示加锁成功,0表示加锁失败。

可选地,上述对目标对象重新加锁可以包括:

对目标对象执行GETSET命令,GETSET命令用于获取目标对象的锁的值;在未获取到目标对象的锁的值或者目标对象的锁超时时,对目标对象重新加锁。

可选地,该方法还可以包括:

当未获取到目标对象的锁的值时,或者当目标对象的锁未超时时,在设定时间内进行休眠,并在休眠后重新获取目标对象的锁的值。

其中,休眠是指逻辑服务器中执行该加锁方法的进程,在此设定时间内不对该数据的目标对象进行任何操作,直到超过设定时间。

可选地,该方法还可以包括:

当对目标对象重新加锁后,监督在目标对象的锁超时之后,目标对象的锁是否被改动;如果在目标对象的锁超时之后,目标对象的锁没有被改动,则删除目标对象的锁。

图3是根据一示例性实施例示出的一种加锁方法的流程图,该方法基于Redis技术实现,采用关键字作为目标对象进行举例说明,如图3所示,该加锁方法适用于前述场景中的逻辑服务器,包括以下步骤:

在步骤S201中,采用SETNX命令对关键字进行加锁操作。

在缓存层和数据库层等数据库中数据通常采用关键字-值(Key-Value)的方式进行存储,其中关键字可以是名称、编号等。以前述货物数量为例,关键字为数量,值为5。

其中,加锁操作是指对缓存层中关键字-值中的关键字加锁,以防止值被其他逻辑服务器修改。

其中,SETNX是SET if Not eXists的简写,意为如果关键字不存在锁则进行加锁。采用SETNX命令对关键字时,如果该关键字不存在锁,则对该关键字进行加锁,此时加锁成功,如果该关键字存在锁,则不对该关键字进行加锁,此时加锁失败。

进一步地,在步骤S201之前,该方法还可以包括:

接收客户端发送的业务请求;根据业务请求确定对应的关键字。

根据业务请求确定对应的关键字可以包括:确定业务请求对应的业务逻辑;确定业务逻辑所对应的关键字。例如,客户端发送的是发货请求,则其对应于发货逻辑,发货逻辑对应的关键字包括货物数量。

在步骤S202中,获取采用SETNX命令对关键字进行加锁操作的返回值,根据返回值,确定对关键字加锁是否成功。当加锁失败时,执行步骤S203。当加锁成功时,则已完成对关键字的加锁操作。

该返回值用于表示加锁操作是否成功,例如如果返回值为第一数值,则此时加锁成功,结束加锁流程;如果返回值为第二数值,则此时加锁失败,执行步骤S203。

其中,第一数值包括但不限于1,第二数值包括但不限于0。

在步骤S203中,通过GET命令获取关键字的锁的值。

其中,GET命令的作用是获取关键字的锁。加锁失败说明该关键字已经被加锁,通过GET命令获取关键字的锁的值。

在步骤S204中,判断是否获取到关键字的锁的值,当未获取到关键字的锁的值时,执行步骤S207,当获取到关键字的锁的值时,执行步骤S205。

判断是否获取到关键字的锁的值,也即判断获取的关键字的锁的值是否为空,获取到的关键字的锁的值为空则表示未获取到关键字的锁的值,若获取到的关键字的锁的值不为空则表示获取到关键字的锁的值。

由于步骤S203和步骤S204是在步骤S201中采用SETNX命令对关键字进行加锁失败时执行的,说明在步骤S201采用SETNX命令对关键字进行加锁时,该关键字已被加锁,而在这种前提下,如果步骤S203未获取到该关键字的锁的值,说明该关键字的锁被其他逻辑服务器删除,此时如果仍然对该关键字进行加锁等操作,可能会因为其他逻辑服务器也在对该关键字进行加锁操作,造成该关键字同时被两个逻辑服务器加锁,因此,当未获取到关键字的锁的值时,执行步骤S209的休眠操作。

在步骤S205中,根据关键字的锁的值判断关键字的锁是否超时,当关键字的锁未超时时,执行步骤S207,当关键字的锁超时时,执行步骤S206。

获取到关键字的锁的值Value 1用于表示该锁的超时时间,通常采用时间戳表示。

此时,判断关键字的锁是否超时可以包括:将Unix时间戳转换为对应的超时时间,判断当前时间是否超过其对应的超时时间(例如北京时间),若超过则说明关键字的锁超时,否则未超时。当前时间可以由逻辑服务器从本地或者网络获取到。

例如,获取到的Unix时间戳为1472968681,则其对应的北京时间为2016/9/4 13:58:01,若当前时间为2016/9/4 15:00:00,则说明该关键字的锁超时。

其中,上述时间戳对应的超时时间可以考虑业务执行所需时间进行设置,例如1毫秒。

在步骤S206中,对关键字执行GETSET命令,GETSET命令用于获取关键字的锁的值,当未获取到关键字的锁的值或者获取到的关键字的锁超时时,完成对关键字的加锁操作;当获取到的关键字的锁未超时时,执行步骤S207

其中,GETSET与GET相比包含了获取锁的值和在锁的值为null或超时时对关键字进行加锁两个动作。

因此,对关键字执行GETSET命令,包括:

步骤2061,获取关键字的锁的值Value 2。

步骤2062,判断是否获取到关键字的锁的值;当未获取到关键字的锁的值时,完成对关键字的加锁操作,当获取到关键字的锁的值时,执行步骤2063。

步骤2063,根据关键字的锁的值判断关键字的锁是否超时;当关键字的锁超时时,完成对关键字的加锁操作,当关键字的锁未超时时,执行步骤S207。

在步骤S207中,在设定时间内进行休眠,并在休眠后重新获取关键字的锁的值。

其中,休眠是指逻辑服务器中执行该加锁方法的进程,在此时间内不对该数据的关键字进行任何操作,直到超过设定时间。休眠时间可以根据关键字对应的数据对应的业务进行设置,例如可以设置为10ms或20ms。

上述步骤S201-S207可以采用如下代码实现:

其中,foo表示关键字。

在步骤S208中,加锁成功后,执行操作指令。

加锁成功后,逻辑服务器会执行业务逻辑,比如发货。

在步骤S209中,操作指令执行完毕后,通过GET命令获取关键字的锁的值。

通过GET命令获取关键字的锁的值Value 3。

在步骤S210中,判断是否获取到关键字的锁的值;当获取到关键字的锁的值时,执行步骤S211,当未获取到关键字的锁的值时,则结束流程。

在步骤S211中,根据关键字的锁的值判断关键字的锁是否超时;当根据Value 1判断关键字的锁超时时,执行步骤S212。

如果关键字的锁未超时,既可以删除该关键字的锁,也可以不执行任何动作。

在步骤S212中,监督在目标对象的锁超时之后,目标对象的锁是否被改动;如果在目标对象的锁超时之后,目标对象的锁没有被改动,则删除目标对象的锁;如果在目标对象的锁超时之后,目标对象的锁被改动,则不删除目标对象的锁。

其中,监督在目标对象的锁超时之后,目标对象的锁是否被改动可以采用WATCH命令实现,WATCH命令在步骤S211之后且步骤S212之前开启,即该方法还可以包括:采用WATCH命令对关键字的锁进行监督。

上述步骤S208-S212可以采用如下代码实现:

doYourJob()

value3=get lock.foo

if(value3!=null&&now()>get lock.foo){

watch lock.foo

multi

del lock.foo

exec

}

上述代码通过watch-multi-exec事务原语实现,如果被监督(watch)的关键字被改动,则multi和exec之间的操作(del lock.foo)不会被执行,如果被监督的关键字未被改动,则执行该操作,也即删除关键字的锁。

本公开通过在判断关键字的锁是否超时之前,执行判断是否获取到关键字的锁的值的操作,避免锁已经被其他主机抢到并删除时仍然判断锁是否超时出现的空指针异常,减少不必要的时间和空间的浪费去处理不能执行完的业务,使得业务逻辑执行的更加完整。并且在上述抢锁过程中,包括两次获取锁的值的过程,避免在第一次判断超时进行加锁,此时该关键字已被其他主机加锁的情况,避免关键字同时被两个主机加锁,提高了独占性。另外,在删除锁时,通过判断在判断出关键字的锁超时之后,关键字的锁没有被改动,避免锁被其他主机获取时产生的误删除操作。

图4是根据一示例性实施例示出的一种加锁装置的框图,该加锁装置可以为逻辑服务器或逻辑服务器的一部分,如图4所示,该装置包括:

获取模块301,用于获取数据库中目标对象的锁的值;

判断模块302,用于判断是否获取到目标对象的锁的值;

处理模块303,用于当获取到目标对象的锁的值时,根据目标对象的锁的值判断目标对象的锁是否超时;

当目标对象的锁超时时,对目标对象重新加锁。

可选地,获取模块301,用于:

采用SETNX命令对目标对象进行加锁操作;

在对目标对象加锁失败时,通过GET命令获取目标对象的锁的值。

可选地,处理模块303,还用于:

获取采用SETNX命令对目标对象进行加锁操作的返回值;

根据返回值,确定对目标对象加锁是否成功。

可选地,处理模块303,还用于:

对目标对象执行GETSET命令,GETSET命令用于获取目标对象的锁的值,并在未获取到目标对象的锁的值或者目标对象的锁超时时,完成对目标对象的加锁操作。

可选地,处理模块303,还用于:

当未获取到目标对象的锁的值时,或者当目标对象的锁未超时时,在设定时间内进行休眠,并在休眠后重新获取目标对象的锁的值。

可选地,获取模块301,用于:

当对目标对象重新加锁后,监督在目标对象的锁超时之后,目标对象的锁是否被改动;如果在目标对象的锁超时之后,目标对象的锁没有被改动,则删除目标对象的锁。

关于上述实施例中的装置,其中各个模块执行操作的具体方式已经在有关该方法的实施例中进行了详细描述,此处将不做详细阐述说明。

图5是根据一示例性实施例示出的一种加锁装置1900的框图,例如,装置1900可以被提供为一服务器。参照图5,装置1900包括处理组件1922,其进一步包括一个或多个处理器,以及由存储器1932所代表的存储器资源,用于存储可由处理组件1922的执行的指令,例如应用程序。存储器1932中存储的应用程序可以包括一个或一个以上的每一个对应于一组指令的模块。此外,处理组件1922被配置为执行指令,以执行上述方法,该方法包括:

获取数据库中目标对象的锁的值;

判断是否获取到目标对象的锁的值;

当获取到目标对象的锁的值时,根据目标对象的锁的值判断目标对象的锁是否超时;

当目标对象的锁超时时,对目标对象重新加锁。

在本公开的一种实现方式中,获取数据库中目标对象的锁的值,包括:

采用SETNX命令对目标对象进行加锁操作;

在对目标对象加锁失败时,通过GET命令获取目标对象的锁的值。

在本公开的另一种实现方式中,方法还包括:

获取采用SETNX命令对目标对象进行加锁操作的返回值;

根据返回值,确定对目标对象加锁是否成功。

在本公开的另一种实现方式中,对目标对象重新加锁,包括:

对目标对象执行GETSET命令,GETSET命令用于获取目标对象的锁的值,并在未获取到目标对象的锁的值或者目标对象的锁超时时,对目标对象重新加锁。

在本公开的另一种实现方式中,该方法还包括:

当未获取到目标对象的锁的值时,或者当目标对象的锁未超时时,在设定时间内进行休眠,并在休眠后重新获取目标对象的锁的值。

在本公开的另一种实现方式中,该方法还包括:

当对目标对象重新加锁后,监督在目标对象的锁超时之后,目标对象的锁是否被改动;如果在目标对象的锁超时之后,目标对象的锁没有被改动,则删除目标对象的锁。

装置1900还可以包括一个电源组件1926被配置为执行装置1900的电源管理,一个有线或无线网络接口1950被配置为将装置1900连接到网络,和一个输入输出(I/O)接口1958。装置1900可以操作基于存储在存储器1932的操作系统,例如Windows ServerTM,Mac OS XTM,UnixTM,LinuxTM,FreeBSDTM或类似。

本领域技术人员在考虑说明书及实践这里公开的发明后,将容易想到本发明的其它实施方案。本申请旨在涵盖本发明的任何变型、用途或者适应性变化,这些变型、用途或者适应性变化遵循本发明的一般性原理并包括本公开未公开的本技术领域中的公知常识或惯用技术手段。说明书和实施例仅被视为示例性的,本发明的真正范围和精神由下面的权利要求指出。

应当理解的是,本发明并不局限于上面已经描述并在附图中示出的精确结构,并且可以在不脱离其范围进行各种修改和改变。本发明的范围仅由所附的权利要求来限制。

当前第1页1 2 3 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1