数据库句柄处理方法、装置和计算机设备与流程

文档序号:11199237阅读:540来源:国知局
数据库句柄处理方法、装置和计算机设备与流程

本发明涉及计算机技术领域,特别是涉及一种数据库句柄处理方法、装置和计算机设备。



背景技术:

随着计算机技术的发展,通过数据库存储文件数据广泛应用于移动终端、pc(personalcomputer,个人计算机)客户端。在使用过程中经常面临多线程并发的挑战,多线程并发发生时,一个线程访问资源时,其他线程需要线性串行地等待其释放资源。当线程并发数超过两个时,较后执行的线程,往往会被互斥锁阻塞很长时间。

传统的数据库句柄处理方法,在数据库打开时获得一个句柄,该句柄作为不同线程的共享资源,一个数据库只对应一个句柄,当多个线程对数据库操作时,很容易在线程访问句柄时产生阻塞,多线程互斥的概率很高,当互斥发生时,线程会频繁进行状态切换,大量消耗cpu线程切换的资源,导致性能下降,



技术实现要素:

基于此,有必要针对上述技术问题,提供一种数据库句柄处理方法、装置和计算机设备,能减少阻塞的发生,减少内存资源的消耗,提高数据库线程并发的性能。

一种数据库句柄处理方法,所述方法包括:

获取数据库操作请求,判断所述数据库操作请求对应的操作是否为事务操作,如果是,则获取所述事务操作对应的事务绑定的第一句柄,返回所述第一句柄;

如果不是事务操作,则判断所述数据库操作请求对应的当前线程中是否存在未完成句柄,如果是,则返回所述未完成句柄;

如果不存在未完成句柄,则从句柄池中通过句柄分发获取第二句柄,返回所述第二句柄。

一种数据库句柄处理装置,所述装置包括:

第一判断模块,用于获取数据库操作请求,判断所述数据库操作请求对应的操作是否为事务操作,如果是,则进入第一句柄返回模块,否则进入第二判断模块;

第一句柄返回模块,用于获取所述事务操作对应的事务绑定的第一句柄,返回所述第一句柄;

第二判断模块,用于判断所述数据库操作请求对应的当前线程中是否存在未完成句柄,如果是,则返回所述未完成句柄,否则进入第二句柄返回模块;

第二句柄返回模块,用于从句柄池中通过句柄分发获取第二句柄,返回所述第二句柄。

一种计算机设备,包括存储器和处理器,所述存储器中存储有计算机可读指令,所述计算机可读指令被所述处理器执行时,使得所述处理器执行以下步骤:

获取数据库操作请求,判断所述数据库操作请求对应的操作是否为事务操作,如果是,则获取所述事务操作对应的事务绑定的第一句柄,返回所述第一句柄;

如果不是事务操作,则判断所述数据库操作请求对应的当前线程中是否存在未完成句柄,如果是,则返回所述未完成句柄;

如果不存在未完成句柄,则从句柄池中通过句柄分发获取第二句柄,返回所述第二句柄。

上述数据库句柄处理方法、装置和计算机设备,通过获取数据库操作请求,判断数据库操作请求对应的操作是否为事务操作,如果是,则获取事务操作对应的事务绑定的第一句柄,返回所述第一句柄,如果不是事务操作,则判断数据库操作请求对应的当前线程中是否存在未完成句柄,如果是,则返回未完成句柄,如果不存在未完成句柄,则从句柄池中通过句柄分发获取第二句柄,返回第二句柄,对于数据库事务操作,可直接返回事务绑定的第一句柄,实现句柄在同一事务不同操作间的重用,对于当前线程中存在未完成句柄的情况,直接返回当前线程的未完成句柄,实现句柄在递归操作的不同操作间重用,可减少向句柄池申请获取句柄的次数,减少向句柄池申请获取句柄时阻塞的发生,且无需每次操作都申请新的句柄,避免句柄冗余,减少内存资源的消耗,减少句柄占用的文件占位符,避免大量数据库操作情况下,句柄冗余导致数据库甚至程序内的所有文件都打开失败的情形,提高了数据库在使用过程中多线程并发的性能。

附图说明

图1为一个实施例中数据库句柄处理方法的应用环境图;

图2为一个实施例中图1中服务器的内部结构图;

图3为一个实施例中图1中终端的内部结构图;

图4为一个实施例中数据库句柄处理方法的流程图;

图5为一个实施例中生成新句柄后队列状态示意图;

图6为一个实施例中将尾部句柄的next指针指向新句柄后的队列状态示意图;

图7为一个实施例中将队列的尾部指针指向新句柄后的队列状态示意图;

图8为一个实施例中句柄分发前队列状态示意图;

图9为一个实施例中移动头部指针后的队列状态示意图;

图10为一个实施例中将句柄分发出去后得到的队列状态示意图;

图11为一个实施例中并发的写操作请求时唤醒写操作重试流程示意图;

图12为一个实施例中数据库句柄处理装置的结构框图;

图13为另一个实施例中数据库句柄处理装置的结构框图;

图14为再一个实施例中数据库句柄处理装置的结构框图;

图15为又一个实施例中数据库句柄处理装置的结构框图;

图16为再一个实施例中数据库句柄处理装置的结构框图;

图17为一个实施例中即时通信应用界面示意图。

具体实施方式

图1为一个实施例中数据库句柄处理方法运行的应用环境图。如图1所示,该应用环境包括终端110和服务器120,其中终端110、服务器120通过网络进行通信。

终端110,可为智能手机、平板电脑、笔记本电脑、台式计算机等,但并不局限于此。数据库操作请求可以是终端110向本地数据库或向服务器120发送的数据库操作请求,也可以是服务器120向本地数据库发送的数据库操作请求。终端110或服务器120根据数据库操作请求对应的数据库操作类型和当前线程的状态为数据库操作请求返回对应的数据库句柄。对于数据库事务操作,可直接返回事务绑定的第一句柄,实现句柄在同一事务不同操作间的重用,对于当前线程中存在未完成句柄的情况,直接返回当前线程的未完成句柄,实现句柄在递归操作的不同操作间重用,可减少向句柄池申请获取句柄的次数,减少向句柄池申请获取句柄时阻塞的发生,且无需每次操作都申请新的句柄,避免句柄冗余,减少内存资源的消耗,减少句柄占用的文件占位符,避免大量数据库操作情况下,句柄冗余导致数据库甚至程序内的所有文件都打开失败的情形,提高了数据库在使用过程中多线程并发的性能。

在一个实施例中,图1中服务器120的内部结构如图2所示,该服务器120包括通过系统总线连接的处理器、存储介质、内存和网络接口。其中,该服务器120的存储介质存储有操作系统、数据库、第一数据库句柄处理装置,数据库用于存储数据,如存储用户数据,第一数据库句柄处理装置用于实现一种适用于服务器120的数据库句柄处理方法。该服务器120的处理器用于提供计算和控制能力,支撑整个服务器120的运行。该服务器120的内存为存储介质中的第一数据库句柄处理装置的运行提供环境。该服务器120的网络接口用于与外部的终端110通过网络连接通信,比如接收终端110发送的数据库操作请求、用户行为数据等。

在一个实施例中,图1中的终端110的内部结构如图2所示,该终端110包括通过系统总线连接的处理器、图形处理单元、存储介质、内存、网络接口、显示屏幕和输入设备。其中,终端110的存储介质存储有操作系统,还包括第二数据库句柄处理装置,该装置用于实现一种适用于终端的数据库句柄处理方法。该处理器用于提供计算和控制能力,支撑整个终端110的运行。终端110中的图形处理单元用于至少提供显示界面的绘制能力,内存为存储介质中的第二数据库句柄处理装置的运行提供环境,网络接口用于与服务器120进行网络通信。显示屏幕用于显示应用界面等,如显示即时通信界面,输入设备用于接收用户输入的命令或数据等。对于带触摸屏的终端110,显示屏幕和输入设备可为触摸屏。图2和图3中示出的结构,仅仅是与本申请方案相关的部分结构的框图,并不构成对本申请方案所应用于其上的服务器或终端的限定,具体的服务器或终端可以包括比图中所示更多或更少的部件,或者组合某些部件,或者具有不同的部件布置。

在一个实施例中,如图4所示,提供了一种数据库句柄处理方法,以应用于上述应用环境中的终端或服务器来举例说明,包括以下步骤:

步骤s210,获取数据库操作请求,判断数据库操作请求对应的操作是否为事务操作,如果是,则进入步骤s220,否则进入步骤s230。

具体地,数据库操作请求用于请求访问数据库访问和对数据库进行操作,数据库操作包括普通操作、事务操作和递归操作等不同类型的操作。普通操作包括对数据库的增加、删除、查找、修改等单次操作,事务操作是对数据库批量的增加、删除、查找、修改等操作,在事务下为原子操作,只包括成功或失败两种结果,不会出现中间结果。与事务关联的各个操作可分别通过不同的线程发送数据库操作请求,与事务关联的操作具有共同的目标,并且是相互依赖的,如果系统只执行这些操作的一个子集,则可能会破坏事务的总体目标。对于一个事务关联的各个操作,都采用相同的句柄,如果是事务操作则进入步骤s220。

步骤s220,获取事务操作对应的事务绑定的第一句柄,返回第一句柄。

具体地,事务操作包括事务开始操作和事务结束操作,事务绑定的第一句柄是在事务开始操作时,从句柄池中通过句柄分发获取第一句柄后,将第一句柄与事务相关联,实现第一句柄与事务的绑定。从而后续同一事务对应的其它操作都采用事务绑定的第一句柄,实现同一事务不同操作间句柄的重用。

在一个实施例中,数据库操作请求对应的操作为事务的开始操作,方法还包括:从句柄池中通过句柄分发获取第一句柄,将第一句柄与事务绑定。

具体地,会在事务开始时,即begintransaction成功时,获得句柄的分发,从句柄池中获取第一句柄,同时将第一句柄与事务绑定,便于后续根据事务标识获取第一句柄。

在一个实施例中,数据库操作请求对应的操作为事务的结束操作,方法还包括:当结束操作执行完毕,将第一句柄回收进入句柄池。

具体地,只有事务对应的所有事务操作都操作完毕,即commit或rollback时,才将与事务绑定的第一句柄回收进入句柄池,在事务对应的事务操作执行过程中,即使其中一个操作执行完毕,第一句柄也不会回收入句柄池,使得第一句柄只能被此事务对应的事务操作调用,不会被其它操作调用,避免了第一句柄进入句柄池后,此事务对应的下一个事务操作再次向句柄池申请第一句柄的步骤,同一事务的后续操作,都将直接返回第一句柄,能减少阻塞的发生,提高数据库线程并发的性能。

步骤s230,判断数据库操作请求对应的当前线程中是否存在未完成句柄,如果是,则返回未完成句柄,如果不存在未完成句柄,则进入步骤s240。

具体的,未完成句柄是指上次从句柄池分发后,未回收进入句柄池中的句柄。递归操作会在第一个操作开始时获得句柄的分发,若在句柄回收之前没有再次发起数据库操作,则是一次普通操作,若发起了新的操作,则为递归操作。如对于递归操作,一次完整的递归操作包括多个子操作,如果只有其中的第一子操作完成,但是一次完整的数据库操作未完成时,若在同一线程再次发起此完整的数据库操作对应的第二子操作,则第一子操作时申请的句柄不回收入句柄池,相当于未完成句柄,第二子操作直接使用当前线程中的未完成句柄。实现句柄在递归操作的不同操作间重用,可减少向句柄池申请获取句柄的次数,减少向句柄池申请获取句柄时阻塞的发生,且无需每次操作都申请新的句柄,避免句柄冗余,减少内存资源的消耗。

步骤s240,从句柄池中通过句柄分发获取第二句柄,返回第二句柄。

具体地,句柄池用于存储可分发的句柄,句柄池中的句柄初始数量可根据需要自定义,如根据项目规模、用户数量进行估算得出。句柄池的结构可根据需要自定义,如表结构、指针节点结构、队列结构等。

本实施例中,通过获取数据库操作请求,判断数据库操作请求对应的操作是否为事务操作,如果是,则获取事务操作对应的事务绑定的第一句柄,返回所述第一句柄,如果不是事务操作,则判断数据库操作请求对应的当前线程中是否存在未完成句柄,如果是,则返回未完成句柄,如果不存在未完成句柄,则从句柄池中通过句柄分发获取第二句柄,返回第二句柄,对于数据库事务操作,可直接返回事务绑定的第一句柄,实现句柄在同一事务不同操作间的重用,对于当前线程中存在未完成句柄的情况,直接返回当前线程的未完成句柄,实现句柄在递归操作的不同操作间重用,可减少向句柄池申请获取句柄的次数,减少向句柄池申请获取句柄时阻塞的发生,且无需每次操作都申请新的句柄,避免句柄冗余,减少内存资源的消耗,减少句柄占用的文件占位符,避免大量数据库操作情况下,句柄冗余导致数据库甚至程序内的所有文件都打开失败的情形,提高了数据库在使用过程中多线程并发的性能。

在一个实施例中,数据库操作请求对应的操作是递归操作,方法还包括:当递归操作对应的操作结束次数与操作开始次数相等时,将递归操作对应的句柄回收进入句柄池。

具体地,由于递归操作在同一个线程中进行多个子操作,整个完整的递归操作对应的多个子操作全部完成时,即操作结束次数与操作开始次数相等时,操作对称时回收句柄。

在一个实施例中,数据库操作请求对应的操作是普通数据库操作,方法还包括:当普通数据库操作结束时,将普通数据库操作对应的句柄回收进入句柄池。

具体地,对于普通数据库操作,在操作结束时就可将普通数据库操作对应的句柄回收进入句柄池。而对于数据库事务访问的情况,句柄池不会在数据库的其中一个事务操作结束后回收句柄,而是在事务的提交或回滚之后才进行回收。通过上述不同数据库操作类型对应不同的句柄回收方式,与不同数据库操作类型对应的句柄分发方式匹配,实现句柄的快速分发,并在句柄分发的过程中避免句柄冗余,减少内存资源的消耗,减少句柄占用的文件占位符,避免大量数据库操作情况下,句柄冗余导致数据库甚至程序内的所有文件都打开失败的情形,提高了数据库在使用过程中多线程并发的性能。句柄池将一个句柄的分发和回收记为一个周期,这个周期可以是一个普通的数据库操作、一次事务操作或一次递归操作对应的周期。

在一个实施例中,普通数据库操作和/或递归操作对应的句柄保存在线程变量中,线程变量在各个线程都存在独立的内存。

具体地,每次普通操作或递归操作,都会将当前句柄保存在线程变量中,如thread_local的变量中,thread_local是c++的一个关键字,它声明的变量将在每个线程都有一份独立的内存,可通过将内存划分为多个独立的单元,各个独立的单元用于保存不同的线程对应的线程变量,各线程的变量互不干涉。当操作未结束之前,再次发起操作时,句柄池将会直接从该线程变量中获得句柄。由于其线程间互不干涉,因此无须加锁保护,从而执行效率更高,进一步提高了数据库多线程并发的性能。

在一个实施例中,句柄池中的句柄组成队列,队列包括头部和尾部,通过原子化的操作实现句柄的分发和回收。

具体地,句柄池的内部是由一个队列组成的,用于实现分发和回收两个动作。分发和回收分别分布在头部和尾部,以减少操作冲突,提高分发效率。句柄池的多线程并发不使用互斥锁,而是使用原子访问,这使得线程间不会因为锁而进入休眠-唤醒的线程切换中,从而避免消耗大量cpu资源。原子化的操作是一种不可分割的操作,要么整体发生,要么根本不发生,即cas(compareandswap),是cpu的一个指令,它将变量a与b比较,若a与b相同,则将a赋值为c,表示为cas(a,b,c)。它的特点是,cpu确保该操作通过一个指令完成。原子访问是cpu指令级别的操作,这类操作只有成功和失败,没有中间状态,可以避免多线程并发时,多个线程运行顺序不一致导致的不确定后果。

在一个实施例中,将第一句柄回收进入句柄池的步骤包括:生成新句柄,将新句柄的next指针指向为空,在队列的尾部指针指向的尾部句柄的next指针指向为空的条件下将尾部句柄的next指针指向所述新句柄,将队列的尾部指针指向新句柄。

具体地,如图5所示,队列包括4个句柄,头部指针指向的头部句柄为句柄1,尾部指针指向的尾部句柄为句柄4,生成新句柄为句柄5,将句柄5的next指针指向为空。由于“将尾部句柄的next指针指向所述新句柄”为一条指令,“将队列的尾部指针指向新句柄”为一条指令,这两条操作指令的实现过程有两步,当存在多线程并发时,可能出现线程1执行完“句柄4的next指针指向句柄5”后,线程2执行“将句柄4的next指针指向句柄5”,然后线程1再执行“将队列的尾部指针指向句柄5”的可能,执行顺序无法预知,从而限制只有当句柄4的next指针指向为空的条件下,才能将句柄4的next指针指向句柄5,即线程1执行完“句柄4的next指针指向句柄5”后,线程2就无法执行“将句柄4的next指针指向句柄5”了,因为此时句柄4的next指针指向不为空了,只有当线程1连续执行完“将句柄4的next指针指向句柄5,将队列的尾部指针指向句柄5”,线程2才能执行“将尾部句柄的next指针指向新句柄”,因为此时尾部句柄已经为句柄5,且句柄5的next指针指向为空,从而形成了原子操作,使得指令的执行顺序确定,保证了线程并发时,句柄回收的正确性。如图6所示,为执行完“将句柄4的next指针指向句柄5”之后队列状态示意图,如图7所示,为“将队列的尾部指针指向句柄5”之后队列状态示意图。

在一个实施例中,从句柄池中通过句柄分发获取第二句柄的步骤包括:将队列头部指针指向从当前句柄移动至下一个句柄,即完成了从队列头部减少一个元素的操作,该操作只有一步,通过原子操作实现。然后将原来的头部指针指向的句柄分发出去。当队列内没有元素时,即头部和尾部都指向空时,直接返回空。如图8所示,为句柄分发前队列状态示意图,如图9所示,为将队列头部指针指向从当前句柄1移动至下一个句柄2后队列状态示意图,如图10所示,为将当前句柄1分发出去后得到的队列状态示意图。

在一个实施例中,数据库操作请求包括多个并发的写操作请求,结合图11所示,方法还包括:

步骤s310,第一线程向数据库发送锁请求,获取锁成功,将数据库锁定。

具体地,对于写操作并发这种必须互斥的情况,当线程1在进行写操作前,第一线程向数据库发送锁请求,锁请求中携带线程1期望的锁状态,数据库判断当前状态符合线程1期望的锁状态,从而线程1获取锁成功,将数据库锁定,开始进行写操作,当线程1进行写操作时,线程2的写操作访问会被阻塞。

步骤s320,第二线程向数据库发送锁请求,获取锁失败,将第二线程期望的锁状态插入锁状态队列,第二线程进入等待状态。

具体地,由于线程1将数据库锁定,第二线程向数据库发送锁请求也不能获取锁,将第二线程期望的锁状态插入锁状态队列。锁状态队列用于存储各个并发线程期望的锁状态,是一个先进先出的队列,如存在先进入的第一锁状态和后进入的第二锁状态,在上一个写操作完成后,先判断当前数据库状态是否符合第一锁状态,从而在当前数据库状态符合第一锁状态时,优先进入第一锁状态对应的线程的唤醒重试流程。将第二线程期望的锁状态插入锁状态队列后,第二线程进入休眠等待状态。

步骤s330,第一线程完成写操作,将数据库解锁,判断数据库当前状态是否满足第二线程期望的锁状态,如果满足,则唤醒第二线程进行写操作重试。

具体地,第一线程完成写操作,将数据库解锁,解锁后,会在线程1比较当前数据库状态与锁状态队列中的第一个状态,即与第二线程期望的锁状态是否匹配,若匹配,则会通过signal唤醒对应的第二线程进行重试操作。如果第二线程期望的锁状态不是锁状态队列中的第一个状态,则需要等待锁状态队列中前面的其他线程期望的锁状态依次与当前数据库状态匹配判断是否满足唤醒条件。

本实施例中,通过将线程期望的锁状态存入锁状态队列,在上一个获取锁的写操作完成后可立即根据锁状态队列中的线程期望的锁状态判断是否可唤醒其它线程重试写操作,而不是通过定时重试的方式,这使得线程不必多次进入线程切换,可大大减少线程切换的次数,同时,在能够重试成功时,线程会第一时间被唤醒,而不至于空等待,能在解锁的第一时间通知到对应的线程。

在一个实施例中,步骤s320中将第二线程期望的锁状态插入锁状态队列的步骤包括:当第二线程是主线程时,将锁状态插入至锁状态队列的头部。

具体地,当一个程序启动时,就有一个进程被操作系统创建,与此同时一个线程也立刻运行,该线程通常叫做程序的主线程。一般程序的交互、动画展示均在主线程运行,若主线程被卡住,则会导致动画卡顿、操作无响应。当即将进入休眠的线程为主线程时,主线程所期望的锁状态会插队到队列的第一位,从而在下次解锁时,主线程可以第一时间被唤醒,使其拥有较高的优先级被唤醒,从而减少主线程,即界面阻塞的时间,大大减少了界面无响应的卡顿现象。

在一个实施例中,如图12所示,提供了一种数据库句柄处理装置,包括:

第一判断模块410,用于获取数据库操作请求,判断数据库操作请求对应的操作是否为事务操作,如果是,则进入第一句柄返回模块420,否则进入第二判断模块430。

第一句柄返回模块420,用于获取事务操作对应的事务绑定的第一句柄,返回所述第一句柄。

第二判断模块430,用于判断数据库操作请求对应的当前线程中是否存在未完成句柄,如果是,则返回未完成句柄,否则进入第二句柄返回模块440。

第二句柄返回模块440,用于从句柄池中通过句柄分发获取第二句柄,返回所述第二句柄。

在一个实施例中,数据库操作请求对应的操作为事务的开始操作,如图13所示,装置还包括:

绑定模块450,用于从句柄池中通过句柄分发获取第一句柄,将第一句柄与事务绑定。

在一个实施例中,数据库操作请求对应的操作为事务的结束操作,如图14所示,装置还包括:

第一回收模块460,用于当结束操作执行完毕,将第一句柄回收进入句柄池。

在一个实施例中,数据库操作请求对应的操作是递归操作,如图15所示,装置还包括:

第二回收模块470,用于当递归操作对应的操作结束次数与操作开始次数相等时,将递归操作对应的句柄回收进入句柄池。

在一个实施例中,所述装置还包括内存,内存包括多个独立的单元,各个独立的单元用于保存不同的线程对应的线程变量,线程变量用于保存普通数据库操作和/或递归操作对应的句柄。

在一个实施例中,所述装置还包括由句柄组成队列的句柄池,队列包括头部和尾部,头部和尾部用于接收原子化的操作实现句柄的分发和回收。

在一个实施例中,第一回收模块450或第二回收模块470还用于生成新句柄,将新句柄的next指针指向为空,将队列的尾部指针指向的尾部句柄的next指针指向新句柄,将队列的尾部指针指向新句柄。

在一个实施例中,数据库操作请求包括多个并发的写操作请求,如图16所示,装置还包括:

写操作通知模块480,用于第一线程向数据库发送锁请求,获取锁成功,将数据库锁定,第二线程向数据库发送锁请求,获取锁失败,将第二线程期望的锁状态插入锁状态队列,第二线程进入等待状态,第一线程完成写操作,将数据库解锁,判断数据库当前状态是否满足第二线程期望的锁状态,如果满足,则唤醒第二线程进行写操作重试。

在一个具体的实施例中,数据库为sqlite,sqlite是一款轻型的数据库,是遵守acid的关系型数据库管理系统,通过独立的句柄池对sqlite句柄进行各线程地分发,减少阻塞的发生。对于必须通过互斥锁保护的共享资源,也通过锁状态队列做到了及时的通知机制,使得等待线程第一时间能获得解锁的通知。同时,通过获取事务操作对应的事务绑定的句柄和当数据库操作请求对应的当前线程中存在未完成句柄时,返回未完成句柄,实现了对sqlite事务和句柄的递归调用的无锁优化,从而大大地提高了sqlite在使用过程中的多线程并发性能。将包括了上述数据库句柄处理方法的sqlite应用于即时通信应用中,如微信中,即时通信应用中的消息数据库可以多线程高效并发地收发消息,同时还能在后台进行数据迁移的操作,如图17所示为即时通信应用中并发收发消息同时在后台进行数据迁移的界面示意图。

在一个实施例中,提供了一种计算机设备,包括存储器和处理器,存储器中存储有计算机可读指令,计算机可读指令被所述处理器执行时,使得所述处理器执行以下步骤:获取数据库操作请求,判断数据库操作请求对应的操作是否为事务操作,如果是,则获取事务操作对应的事务绑定的第一句柄,返回第一句柄,如果不是事务操作,则判断数据库操作请求对应的当前线程中是否存在未完成句柄,如果是,则返回未完成句柄,如果不存在未完成句柄,则从句柄池中通过句柄分发获取第二句柄,返回第二句柄。

上述计算机设备,通过获取数据库操作请求,判断数据库操作请求对应的操作是否为事务操作,如果是,则获取事务操作对应的事务绑定的第一句柄,返回所述第一句柄,如果不是事务操作,则判断数据库操作请求对应的当前线程中是否存在未完成句柄,如果是,则返回未完成句柄,如果不存在未完成句柄,则从句柄池中通过句柄分发获取第二句柄,返回第二句柄,对于数据库事务操作,可直接返回事务绑定的第一句柄,实现句柄在同一事务不同操作间的重用,对于当前线程中存在未完成句柄的情况,直接返回当前线程的未完成句柄,实现句柄在递归操作的不同操作间重用,可减少向句柄池申请获取句柄的次数,减少向句柄池申请获取句柄时阻塞的发生,且无需每次操作都申请新的句柄,避免句柄冗余,减少内存资源的消耗,减少句柄占用的文件占位符,避免大量数据库操作情况下,句柄冗余导致数据库甚至程序内的所有文件都打开失败的情形,提高了数据库在使用过程中多线程并发的性能。

在一个实施例中,数据库操作请求对应的操作为事务的开始操作,计算机可读指令还使得处理器执行以下步骤:从句柄池中通过句柄分发获取第一句柄,将第一句柄与事务绑定。

在一个实施例中,数据库操作请求对应的操作为所述事务的结束操作,计算机可读指令还使得处理器执行以下步骤:当结束操作执行完毕,将第一句柄回收进入句柄池。

在一个实施例中,数据库操作请求对应的操作是递归操作,计算机可读指令还使得处理器执行以下步骤:当递归操作对应的操作结束次数与操作开始次数相等时,将递归操作对应的句柄回收进入句柄池。

在一个实施例中,数据库操作请求对应的操作是普通数据库操作,计算机可读指令还使得处理器执行以下步骤:当普通数据库操作结束时,将普通数据库操作对应的句柄回收进入句柄池。

在一个实施例中,普通数据库操作和/或递归操作对应的句柄保存在线程变量中,线程变量在各个线程都存在独立的内存。

在一个实施例中,句柄池中的句柄组成队列,队列包括头部和尾部,通过原子化的操作实现句柄的分发和回收。

在一个实施例中,处理器所执行的将所述第一句柄回收进入句柄池包括:生成新句柄,将新句柄的next指针指向为空;将队列的尾部指针指向的尾部句柄的next指针指向新句柄;将队列的尾部指针指向新句柄。

在一个实施例中,数据库操作请求包括多个并发的写操作请求,计算机可读指令还使得处理器执行以下步骤:第一线程向数据库发送锁请求,获取锁成功,将数据库锁定,第二线程向数据库发送锁请求,获取锁失败,将第二线程期望的锁状态插入锁状态队列,第二线程进入等待状态,第一线程完成写操作,将数据库解锁,判断数据库当前状态是否满足第二线程期望的锁状态,如果满足,则唤醒第二线程进行写操作重试。

在一个实施例中,处理器所执行的将第二线程期望的锁状态插入所述锁状态队列包括:当第二线程是是主线程时,将锁状态插入至锁状态队列的头部。

在一个实施例中,提供了一个或多个存储有计算机可读指令的非易失性可读存储介质,该计算机可读指令被一个或多个处理器执行时,使得一个或多个处理器执行以下步骤:获取数据库操作请求,判断数据库操作请求对应的操作是否为事务操作,如果是,则获取事务操作对应的事务绑定的第一句柄,返回第一句柄,如果不是事务操作,则判断数据库操作请求对应的当前线程中是否存在未完成句柄,如果是,则返回未完成句柄,如果不存在未完成句柄,则从句柄池中通过句柄分发获取第二句柄,返回第二句柄。

上述非易失性可读存储介质中的计算机可读指令被处理器执行时,通过获取数据库操作请求,判断数据库操作请求对应的操作是否为事务操作,如果是,则获取事务操作对应的事务绑定的第一句柄,返回所述第一句柄,如果不是事务操作,则判断数据库操作请求对应的当前线程中是否存在未完成句柄,如果是,则返回未完成句柄,如果不存在未完成句柄,则从句柄池中通过句柄分发获取第二句柄,返回第二句柄,对于数据库事务操作,可直接返回事务绑定的第一句柄,实现句柄在同一事务不同操作间的重用,对于当前线程中存在未完成句柄的情况,直接返回当前线程的未完成句柄,实现句柄在递归操作的不同操作间重用,可减少向句柄池申请获取句柄的次数,减少向句柄池申请获取句柄时阻塞的发生,且无需每次操作都申请新的句柄,避免句柄冗余,减少内存资源的消耗,减少句柄占用的文件占位符,避免大量数据库操作情况下,句柄冗余导致数据库甚至程序内的所有文件都打开失败的情形,提高了数据库在使用过程中多线程并发的性能。

在一个实施例中,数据库操作请求对应的操作为事务的开始操作,计算机可读指令还使得处理器执行以下步骤:从句柄池中通过句柄分发获取第一句柄,将第一句柄与事务绑定。

在一个实施例中,数据库操作请求对应的操作为所述事务的结束操作,计算机可读指令还使得处理器执行以下步骤:当结束操作执行完毕,将第一句柄回收进入句柄池。

在一个实施例中,数据库操作请求对应的操作是递归操作,计算机可读指令还使得处理器执行以下步骤:当递归操作对应的操作结束次数与操作开始次数相等时,将递归操作对应的句柄回收进入句柄池。

在一个实施例中,数据库操作请求对应的操作是普通数据库操作,计算机可读指令还使得处理器执行以下步骤:当普通数据库操作结束时,将普通数据库操作对应的句柄回收进入句柄池。

在一个实施例中,普通数据库操作和/或递归操作对应的句柄保存在线程变量中,线程变量在各个线程都存在独立的内存。

在一个实施例中,句柄池中的句柄组成队列,队列包括头部和尾部,通过原子化的操作实现句柄的分发和回收。

在一个实施例中,处理器所执行的将所述第一句柄回收进入句柄池包括:生成新句柄,将新句柄的next指针指向为空;将队列的尾部指针指向的尾部句柄的next指针指向新句柄;将队列的尾部指针指向新句柄。

在一个实施例中,数据库操作请求包括多个并发的写操作请求,计算机可读指令还使得处理器执行以下步骤:第一线程向数据库发送锁请求,获取锁成功,将数据库锁定,第二线程向数据库发送锁请求,获取锁失败,将第二线程期望的锁状态插入锁状态队列,第二线程进入等待状态,第一线程完成写操作,将数据库解锁,判断数据库当前状态是否满足第二线程期望的锁状态,如果满足,则唤醒第二线程进行写操作重试。

在一个实施例中,处理器所执行的将第二线程期望的锁状态插入所述锁状态队列包括:当第二线程是是主线程时,将锁状态插入至锁状态队列的头部。

本领域普通技术人员可以理解实现上述实施例方法中的全部或部分流程,是可以通过计算机程序来指令相关的硬件来完成,所述程序可存储于一计算机可读取存储介质中,如本发明实施例中,该程序可存储于计算机系统的存储介质中,并被该计算机系统中的至少一个处理器执行,以实现包括如上述各方法的实施例的流程。其中,所述存储介质可为磁碟、光盘、只读存储记忆体(read-onlymemory,rom)或随机存储记忆体(randomaccessmemory,ram)等。

以上所述实施例的各技术特征可以进行任意的组合,为使描述简洁,未对上述实施例中的各个技术特征所有可能的组合都进行描述,然而,只要这些技术特征的组合不存在矛盾,都应当认为是本说明书记载的范围。

以上所述实施例仅表达了本发明的几种实施方式,其描述较为具体和详细,但并不能因此而理解为对发明专利范围的限制。应当指出的是,对于本领域的普通技术人员来说,在不脱离本发明构思的前提下,还可以做出若干变形和改进,这些都属于本发明的保护范围。因此,本发明专利的保护范围应以所附权利要求为准。

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