一种数据加锁检测方法、设备及计算机可读存储介质与流程

文档序号:23590086发布日期:2021-01-08 14:26阅读:83来源:国知局
一种数据加锁检测方法、设备及计算机可读存储介质与流程
本申请实施例涉及金融科技(fintech)的数据处理
技术领域
,涉及但不限于一种数据加锁检测方法、设备及计算机可读存储介质。
背景技术
:随着计算机计算的发展,越来越多的技术应用在金融领域,传统金融业正在逐步向金融科技(fintech)转变,但由于金融行业的安全性、实时性要求,也对技术提出了更高的要求。当前随着银行金融体系的不断丰富和完善,大量业务迁移到线上处理,金融业务相互穿插嵌套,系统在同一时间点处理同一用户的业务数据的概率越来越高,如何保证“并发”场景中共享数据的一致性和有效性,是银行交易中需要重点考虑的问题。目前,依赖于开发人员人工手动进行代码评审、并发测试等方法来检测并发数据异常的现象。然而,这些方法不仅受到人为因素影响,而且并发测试由于模拟环境限制也往往不能完全覆盖生产真实场景,所以,无法有效检测出并发问题。技术实现要素:本申请实施例提供一种数据加锁检测方法、设备及计算机可读存储介质,以解决相关技术中不仅受到人工手动加锁检测时人为因素影响,而且并发测试由于模拟环境限制也往往不能完全覆盖生产真实场景,从而无法有效检测出并发问题。本申请实施例的技术方案是这样实现的:本申请实施例提供一种方法,包括:若开启事务,获取所述事务对应的数据库访问接口的第一方法名和第一表名;若保存的强制加锁定义表包括所述第一表名,且所述第一方法名表征对所述事务关联的数据执行更新操作,从已加锁数据缓存区中所述事务对应的缓存区查找所述数据,得到检测结果;若所述检测结果表征所述事务对应的缓存区不存在所述数据,从所述强制加锁定义表中获取与所述第一表名对应的处理策略;基于所述处理策略,对所述数据进行处理。本申请实施例提供一种设备,包括:存储器,用于存储可执行指令;处理器,用于执行存储器中存储的可执行指令时,实现上述的方法。本申请实施例提供一种计算机可读存储介质,存储有可执行指令,用于引起处理器执行时,实现上述的方法。本申请实施例具有以下有益效果:通过若开启事务,获取所述事务对应的数据库访问接口的第一方法名和第一表名;若保存的强制加锁定义表包括所述第一表名,且所述第一方法名表征对所述事务关联的数据执行更新操作,从已加锁数据缓存区中所述事务对应的缓存区查找所述数据,得到检测结果;若所述检测结果表征所述事务对应的缓存区不存在所述数据,从所述强制加锁定义表中获取与所述第一表名对应的处理策略;基于所述处理策略,对所述数据进行处理;如此,在更新数据之前通过获取的事务对应的数据库访问接口的表名,进行加锁检测,有效避免人工手动加锁检测受人为因素影响导致准确率低的现象,同时基于上述表名对真实事务环境进行加锁检测避免了模拟环境限制不能完全覆盖生产真实场景的问题,实现自动且精确的加锁检测,实现有效检测出并发问题,并且当检测出未加锁时,基于表名对应的处理策略对数据进行相应的处理,提高检测加锁检测效率和检测准确性,避免并发问题的出现,对为加锁现象进行合理处理,提高数据的安全性。附图说明图1是本申请实施例提供的一种多线程并发场景的示意图;图2是本申请实施例提供的终端的一个可选的架构示意图;图3是本申请实施例提供的数据加锁检测方法的一个可选的流程示意图;图4是本申请实施例提供的缓存数据存储结构的示意图;图5是本申请实施例提供的数据加锁检测方法的一个可选的流程示意图;图6是本申请实施例提供的数据加锁检测方法的一个可选的流程示意图;图7是本申请实施例提供的数据加锁检测方法的一个可选的流程示意图;图8是本申请实施例提供的数据加锁检测方法的一个可选的流程示意图。具体实施方式为了使本申请的目的、技术方案和优点更加清楚,下面将结合附图对本申请作进一步地详细描述,所描述的实施例不应视为对本申请的限制,本领域普通技术人员在没有做出创造性劳动前提下所获得的所有其它实施例,都属于本申请保护的范围。在以下的描述中,涉及到“一些实施例”,其描述了所有可能实施例的子集,但是可以理解,“一些实施例”可以是所有可能实施例的相同子集或不同子集,并且可以在不冲突的情况下相互结合。除非另有定义,本申请实施例所使用的所有的技术和科学术语与属于本申请实施例的
技术领域
的技术人员通常理解的含义相同。本申请实施例所使用的术语只是为了描述本申请实施例的目的,不是旨在限制本申请。1)java虚拟机(javavirtualmachine,jvm),一个jvm表现为一个java进程。2)排他锁,写锁,独占锁,是一种悲观锁。用于数据修改操作,确保不会同时对同一资源进行多重更新。3)spring,一种开源的、基于java程序语言的应用程序框架。4)面向切面的编程(aspectorientedprogramming,aop),用于定义拦截器。本申请可以使用spring的aop实现拦截器,当然,本申请还可以基于任何支持aop功能的工具实现拦截器。5)mybatis,一种开源的、基于java程序语言的数据持久化框架。本申请不仅适用于mybatis,其他对象映射框架如hibernate也是适用的,只要数据访问对象(dataaccessobject,dao)命名和其方法命名规则统一,aop拦截器就可以做拦截处理。6)mybatis代码生成器(mybatisgenerator),本申请使用了mybatisgenrator生成访问数据库的代码,使得所有mapper和其方法的命名规则统一。7)访问数据库的接口(mappermybatis),其作用等同于dao。8)域(domain),一个domain类对应于一个数据库表定义,一个domain对象对应于一条表记录。为了更好地理解本申请实施例中提供的数据加锁检测方法,首先对相关技术中的数据加锁检测方法进行说明:随着银行金融体系的不断丰富和完善,大量业务迁移到线上处理,金融业务相互穿插嵌套,系统在同一时间点处理同一用户的业务数据的概率越来越高,如何保证“并发”场景中共享数据的一致性和有效性,是银行交易中需要重点考虑的问题。银行账户管理相关的信息,特别是余额部分,如果出现数据问题将会成为重大安全事件。通常在多线程开发中,对于共享数据的修改会通过加排他锁处理,特别是在金融系统领域要保证数据的绝对安全性。通过加锁机制保证数据的原子性更新,也就是保证数据在一个线程更新的过程中不会被其它线程同步更新,使得该线程获取数据并更新数据的操作是安全的。相关技术中,一种安全的对共享数据更新的方法通常包括如下几个步骤:(1)开启事务starttransaction;(2)根据主键查询数据并加排他锁select*fromca_acct_mastwhereacct_no=‘0001’forupdate;(3)更新数据updateca_acct_mastsetbalance=200whereacct_no=‘0001’;(4)提交事务释放锁committransaction。然而,并不是每个开发人员在更新数据时都能充分考虑到“并发”场景并按这个步骤规范处理。如果没有对共享数据加锁保证数据的原子性更新,两个线程又恰好同时执行,将会出现难以预料的错误。图1是两个线程t1和t2并发更新余额的示例,首先t1获取账户余额100,cpu执行线程调度后t2执行,t2获取账户余额也为100,然后又发生线程切换,t1更新余额数据为300后,t2重新获得cpu使用权,t2再更新余额数据并没有取更新后的余额300而是以旧的余额100去做更新,导致最后线程t1更新的数据丢失。在真实场景中,这将直接造成用户财产的损失,这是一家银行系统最不应该犯的致命错误。因此,多线程开发中共享数据的安全性特别重要,但是目前的方案基本都是依赖于开发人员人工手动进行代码评审、并发测试等方法来检测并发数据异常的现象。这些方案通常效率不高,主观性较强,安全性也没办法绝对保证,开发和评审大多受人为因素影响,并发测试由于模拟环境限制也往往不能完全覆盖生产真实场景,只能尽量发现问题,无法有效检测出并发问题,从而并不能避免并发问题的出现。为此,本申请提供一种数据加锁检测方法,在更新数据之前实现精确的加锁检测,实现有效检测出并发问题,并且当检测出未加锁时,基于表名对应的处理策略对数据进行相应的处理,提高检测加锁检测效率和检测准确性,避免并发问题的出现,对为加锁现象进行合理处理,提高数据的安全性。下面说明本申请实施例提供的数据加锁检测设备的示例性应用,本申请实施例提供的数据加锁检测设备可以实施为笔记本电脑,平板电脑,台式计算机,移动设备(例如,移动电话,便携式音乐播放器,个人数字助理,专用消息设备,便携式游戏设备),智能机器人等任意具有屏幕显示功能的终端,也可以实施为服务器。下面,将说明数据加锁检测设备实施为终端时的示例性应用。参见图2,图2是本申请实施例提供的终端100的结构示意图,图2所示的终端100包括:至少一个处理器110、至少一个网络接口120、用户接口130和存储器150。终端100中的各个组件通过总线系统140耦合在一起。可理解,总线系统140用于实现这些组件之间的连接通信。总线系统140除包括数据总线之外,还包括电源总线、控制总线和状态信号总线。但是为了清楚说明起见,在图2中将各种总线都标为总线系统140。处理器110可以是一种集成电路芯片,具有信号的处理能力,例如通用处理器、数字信号处理器(dsp,digitalsignalprocessor),或者其他可编程逻辑器件、分立门或者晶体管逻辑器件、分立硬件组件等,其中,通用处理器可以是微处理器或者任何常规的处理器等。用户接口130包括使得能够呈现媒体内容的一个或多个输出装置131,包括一个或多个扬声器和/或一个或多个视觉显示屏。用户接口130还包括一个或多个输入装置132,包括有助于用户输入的用户接口部件,比如键盘、鼠标、麦克风、触屏显示屏、摄像头、其他输入按钮和控件。存储器150可以是可移除的,不可移除的或其组合。示例性地硬件设备包括固态存储器,硬盘驱动器,光盘驱动器等。存储器150可选地包括在物理位置上远离处理器110的一个或多个存储设备。存储器150包括易失性存储器或非易失性存储器,也可包括易失性和非易失性存储器两者。非易失性存储器可以是只读存储器(readonlymemory,rom),易失性存储器可以是随机存取存储器(randomaccessmemory,ram)。本申请实施例描述的存储器150旨在包括任意适合类型的存储器。在一些实施例中,存储器150能够存储数据以支持各种操作,这些数据的示例包括程序、模块和数据结构或者其子集或超集,下面示例性说明。操作系统151,包括用于处理各种基本系统服务和执行硬件相关任务的系统程序,例如框架层、核心库层、驱动层等,用于实现各种基础业务以及处理基于硬件的任务;网络通信模块152,用于经由一个或多个(有线或无线)网络接口120到达其他计算设备,示例性地网络接口120包括:蓝牙、无线相容性认证(wifi)、和通用串行总线(universalserialbus,usb)等;输入处理模块153,用于对一个或多个来自一个或多个输入装置132之一的一个或多个用户输入或互动进行检测以及翻译所检测的输入或互动。在一些实施例中,本申请实施例提供的装置可以采用软件方式实现,图2示出了存储在存储器150中的一种数据加锁检测装置154,该数据加锁检测装置154可以是终端100中的数据加锁检测装置,其可以是程序和插件等形式的软件,包括以下软件模块:获取模块1541、处理模块1542,这些模块是逻辑上的,因此根据所实现的功能可以进行任意的组合或进一步拆分。将在下文中说明各个模块的功能。在另一些实施例中,本申请实施例提供的装置可以采用硬件方式实现,作为示例,本申请实施例提供的装置可以是采用硬件译码处理器形式的处理器,其被编程以执行本申请实施例提供的数据加锁检测方法,例如,硬件译码处理器形式的处理器可以采用一个或多个应用专用集成电路(applicationspecificintegratedcircuit,asic)、dsp、可编程逻辑器件(programmablelogicdevice,pld)、复杂可编程逻辑器件(complexprogrammablelogicdevice,cpld)、现场可编程门阵列(field-programmablegatearray,fpga)或其他电子元件。下面将结合本申请实施例提供的终端100的示例性应用和实施,说明本申请实施例提供的数据加锁检测方法。参见图3,图3是本申请实施例提供的数据加锁检测方法的一个可选的流程示意图,将结合图3示出的步骤进行说明,步骤s201,若开启事务,获取事务对应的数据库访问接口的第一方法名和第一表名。本申请实施例中,终端上运行有jvm,jvm采用mybatis或hibernate等基于java程序语言的数据持久化框架实现对数据库进行操作。比如在金融领域中,经常需要使用jvm访问金融数据库表,如账务信息表,开户信息表,金融交易信息表等,这一过程中会用到缓存技术以满足金融业务的访问速度要求。一些实施例中,终端在执行开启事务,获得事务对应的数据库访问接口的第一方法名和第一表名的步骤之前,可以预先在所有mapper上设置拦截器。终端的系统运行时,每次对mapper的调用,都会被拦截器拦截,拦截器获取到当次调用的mapper类名、mapper方法名和传入参数。其中,终端根据mapper类名映射得到mapper表名。这里,mapper方法名包括第一方法名,mapper表名包括第一表名。示例性的,以采用mybatis对数据库进行操作为例进行说明。mybatis访问数据库的接口称为mapper,当终端开启事务的情况下,在jvm的任一线程中检测到调用数据库访问接口mapper的指令时,获取当前调用的mapper类名、mapper方法名和传入参数,其中,传入参数用于表示要进行读写的域对象,一个域对象对应于一条数据库表记录。一些实施例中,终端设置拦截器不仅能够拦截创建spring事务的代码,还能够初始化当前事务的已加锁数据缓存区。在一种可实现场景中,终端通过如下步骤设置拦截器,步骤a,先定义两个aop切面。其中,这两个切面的组合表示spring事务的开始。终端基于如下代码定义切面1:@pointcut("target(org.springframework.transaction.platformtransactionmanager)")publicvoidisplatformtransactionmanager(){}终端基于如下代码定义切面2:@pointcut("execution(org.springframework.transaction.transactionstatusgettransaction(org.springframework.transaction.transactiondefinition)))")publicvoidgettransaction(){}步骤b,针对上述两个切面,设置一个拦截器。设置好的拦截器为:@around("isplatformtransactionmanager()&&gettransaction()")进一步地,终端通过拦截器执行初始化的步骤,为执行过加锁操作的数据分配存储区域,具体地,终端在事务创建时,通过上述拦截器为当前事务新建一个空集合的缓存区,并置入已加锁数据缓存区manlockcache的栈顶,上述新建的缓存区用于保存本层事务中执行过加锁操作的数据。示例性的,本申请终端可以通过mybatisgenerator来生成访问数据库的代码,以提高开发效率,并使得所有mapper和其方法的命名规则统一,便于拦截器拦截处理。当然,本申请也可以不使用mybatisgenerator,只要mybatismapper命名和其方法命名规则统一,aop拦截器即可对其进行拦截。本申请其他实施例中,终端还可以通过拦截器将一个强制加锁检测适配器manlockadapter注册到当前事务中,用于spring事务结束时清空当前事务已加锁数据的缓存。需要说明的是,每个事务都有一个独立的事务上下文,事务结束后,上下文包括manlockadapter会被清理,所以每次事务开始时,都需要对当前事务注册manlockadapter。步骤s202,若保存的强制加锁定义表包括第一表名,且第一方法名表征对事务关联的数据执行更新操作,从已加锁数据缓存区中事务对应的缓存区查找数据,得到检测结果。本申请实施例中,终端确定保存的强制加锁定义表包括第一表名,则说明第一表名在强制加锁定义表中已配置,进而获取第一方法名执行对应的操作,在第一方法名表征对事务关联的数据执行更新操作,从已加锁数据缓存区中事务对应的缓存区查找数据,得到已加锁数据缓存区中事务对应的缓存区是否包括上述数据的检测结果。示例性的,强制加锁定义表(sys_manlock_def)如下所示,上述强制加锁定义表配置了系统需要做强制加锁检查的相关业务表,该强制加锁定义表能够实现动态配置。比如有一个客户账户信息主表ca_acct_mast,主键为acct_no,配置如下:mapper_nameprimary_keythrow_exceptioncaacctmastmapperacctno1其中,表中的primary_key主键字段主要用来和mapper_name结合表示特定的加锁数据。每个配置表可根据throw_exception字段配置检查异常的处理方式,直接报错中断流程或者仅打印告警日志允许流程继续执行。通过支持不同报错级别的设置,该方案可灵活运用于不同的环境或业务场景。步骤s203,若检测结果表征事务对应的缓存区不存在数据,从强制加锁定义表中获取与第一表名对应的处理策略。本申请实施例中,终端确定检测结果表征事务对应的缓存区不存在数据,说明上述数据在当前事务中未执行过加锁处理,存在并发更新共享数据的风险,则从强制加锁定义表中获取与第一表名对应的处理策略,该处理策略用于对数据进行处理。可见,本申请实现了特定数据表的强制加锁检测,通过执行在同一个事务中更新数据之前必须加锁的策略,能够从源头上避免问题从而保证金融数据的安全性。步骤s204,基于处理策略,对数据进行处理。需要说明的是,终端确定保存的强制加锁定义表不包括所述第一表名时,说明第一表名在强制加锁定义表中未配置,则直接执行数据访问流程。由上述可知,本申请提出了针对特定数据表的强制加锁检测,通过在运行时环境对重要数据表更新操作做加锁检查,保证金融数据的安全性。该方法的检测机制可以把问题第一时间在测试环境中暴露出来,从而有机会让开发人员纠正问题,尽量避免把问题带到生产环境中。当然在生产环境中,也可以使用告警的策略来发现隐患问题。本申请提供的数据加锁检测方法,通过若开启事务,获取所述事务对应的数据库访问接口的第一方法名和第一表名;若保存的强制加锁定义表包括所述第一表名,且所述第一方法名表征对所述事务关联的数据执行更新操作,从已加锁数据缓存区中所述事务对应的缓存区查找所述数据,得到检测结果;若所述检测结果表征所述事务对应的缓存区不存在所述数据,从所述强制加锁定义表中获取与所述第一表名对应的处理策略;基于所述处理策略,对所述数据进行处理;如此在更新数据之前实现精确的加锁检测,实现有效检测出并发问题,并且当检测出未加锁时,基于表名对应的处理策略对数据进行相应的处理,提高检测加锁检测效率和检测准确性,避免并发问题的出现,对为加锁现象进行合理处理,提高数据的安全性。在一些实施例中,上述事务为主事务,主事务嵌套至少一个子事务,主事务和任一子事务在已加锁数据缓存区中具有独立的缓存区。可见,本申请提供的数据加锁检测方法支持嵌套事务的强制加锁检查。在实际应用中,终端定义一个适配器,如manlockadapter,置入一个aftercompletion(intstatus)方法。当spring事务完成时,会触发这个方法的调用。这个方法会在当前事务结束时将缓存区manlockcache栈顶的元素移除(如果强制加锁缓存区有事务存在),也就是清除当前事务中缓存的已执行过加锁操作的数据。当前事务结束后回到上个事务,继续执行上个事务的数据访问和强制加锁检测,从而支持嵌套型事务。进一步地,结合图4所示,对本申请的缓存数据存储结构即已加锁数据缓存区进行说明,已加锁数据缓存区是一个线程级变量(threadlocal),用来存储各个事务中已执行过加锁的数据,表现为一个堆栈stack,结构如下:staticthreadlocal<stack<hashset<string>>>manlockstack=threadlocal.withinitial(stack<hashset<string>>::new);参见图4所示,缓存数据存储结构支持嵌套型事务,每一层事务都使用了一个独立的已加锁数据缓存区,各层事务的缓存数据被隔离。栈中每个元素代表当前线程各事务中执行过加锁操作的数据集合,栈顶元素对应当前事务。示例性的,当前事务对应的加锁数据集合subtrxn包括如下数据:tabakeya1,tabakeyc1,tabakeyb1_keyb2等。其中,加锁数据通过表定义对应的domainname+主键pk(或通过“_”连接的复合主键)的形式表示。比如,有一个客户账户信息主表,表名为ca_acct_mast,其主键为acct_no,其中有两个账号0001,0002,则执行加锁之后数据集合里面会包含caacctmast0001,caacctmast0002;比如,有一个交易明细表,表名为ca_txn_detl,其主键为acct_no+seq_no,其中账号0001有两条序号为1和2的记录,则执行加锁之后数据集合里面会包含catxndetl0001_1,catxndetl0001_2。在一些实施例中,步骤s204基于处理策略,对数据进行处理,包括以下步骤:禁止对数据执行更新操作,并确定事务处理失败。由此,终端确定存在并发更新共享数据的风险,禁止对数据执行更新操作,有效提高了数据的安全性。进一步地,确定事务处理失败之后,终端从已加锁数据缓存区中移除事务对应的缓存区,从而释放存储空间,提升终端的处理效率。在另一些实施例中,步骤s204基于处理策略,对数据进行处理,包括以下步骤:生成提示信息并输出提示信息;提示信息用于提示在事务中未对数据执行过加锁处理;对数据执行更新操作,并确定事务处理成功。进一步地,确定事务处理成功之后,终端从已加锁数据缓存区中移除事务对应的缓存区,从而释放存储空间,提升终端的处理效率。在一些实施例中,在步骤s201的获取事务对应的数据库访问接口的第一方法名和第一表名之后,如图5所示,本申请提供的数据加锁检测方法还包括以下步骤:步骤s301,若强制加锁定义表包括第一表名,且第一方法名表征对事务关联的数据执行插入操作或查询加锁操作,将数据写入事务对应的缓存区。本申请实施例中,终端确定保存的强制加锁定义表包括第一表名,则说明第一表名在强制加锁定义表中已配置,进而获取第一方法名执行对应的操作。进一步地,终端确定第一方法名表征对事务关联的数据执行插入操作或查询加锁操作,将数据写入事务对应的缓存区。其中,插入操作代表该数据是在当前事务中首次建立的,数据库事务的隔离性决定了事务提交前该数据不会被其他事务读取并且更新到,为了校验规则的统一性,对本层事务中先插入后更新的操作,也按照强制锁检测的流程处理,将插入操作视同加锁操作把用domainname+pk表示的数据放入本层事务的已加锁数据缓存区。步骤s302,对事务对应的缓存区中的数据执行读写操作,并确定事务处理成功。进一步地,确定事务处理成功之后终端从已加锁数据缓存区中移除事务对应的缓存区。在一些实施例中,为了校验规则的统一性,对本层事务中先插入后更新的操作,也按照强制锁检测的流程处理,即在步骤s205若强制加锁定义表包括第一表名,且第一方法名表征对事务关联的数据执行插入操作或查询加锁操作,将数据写入事务对应的缓存区之后,如图6所示,本申请提供的数据加锁检测方法还包括以下步骤:步骤s401,获取数据库访问接口的第二方法名和第二表名。步骤s402,若强制加锁定义表包括第二表名,且第二方法名表征对数据执行更新操作,从事务对应的缓存区查找数据,得到表征事务对应的缓存区存在数据的检测结果。本申请实施例中,终端确定保存的强制加锁定义表包括第二表名,则说明第二表名在强制加锁定义表中已配置,进而获取第二方法名执行对应的操作。进一步地,终端确定第二方法名表征对数据执行更新操作,从事务对应的缓存区查找数据,得到表征事务对应的缓存区存在数据的检测结果。步骤s403,对数据执行更新操作,并确定事务处理成功。进一步地,确定事务处理成功之后,终端从已加锁数据缓存区中移除事务对应的缓存区。在一些实施例中,在步骤s201中获取事务对应的数据库访问接口的第一方法名和第一表名之前,如图7所示,本申请提供的数据加锁检测方法还包括以下步骤:步骤s501,获取触发事件,触发事件用于更新强制加锁定义表中的表名。这里,触发事件包括用于更新强制加锁定义表中的表名的输入操作;触发事件还包括触发指令,该触发指令可以是终端设置的定时更新强制加锁定义表中的表名的指令。本申请实施例中,强制加锁定义表中的表名包括上述第一表名和上述第二表名。步骤s502,更新强制加锁定义表中的表名。步骤s503,加载强制加锁定义表至java虚拟机内存中。示例性的,在一些实施例中,为了减少加锁检查时的数据库交互,对配置的强制加锁定义表采取jvm级缓存方案。此处将上述定义表插入缓存定义表sys_cache_def,配置如下:终端的系统启动时加载强制加锁定义表数据到jvm内存。后期因需求变更,有其他特定数据表需要做强制加锁检查时,需要更新强制加锁定义表并同步刷新缓存定义表配置中上述记录的refresh_no。终端的系统后台线程每隔特定时间如30s会扫描缓存定义表,根据refresh_no的变化来刷新jvm缓存数据,实现强制加锁检查表的动态配置。可见,本申请实现了特定数据表如强制加锁定义表的动态配置,可根据实际场景灵活配置需要做加锁检测的数据表,且调整时仅仅需要调整配置即可,无需停机做任何代码上的修改。下面,结合图8所示,将说明本申请实施例在一个实际的应用场景中的示例性应用,该方法应用于终端,包括如下步骤:步骤s601,确定事务开始。步骤s602,定义下述拦截器,拦截器会拦截创建spring事务的方法,用于注册强制加锁检测适配器manlockadapter,以及初始化当前事务的已加锁数据缓存区。定义的拦截器为@around("execution(public*com.xxx..mapper..*.*(..))&&bean(*mapper)")。拦截器会拦截所有通过mapper进行数据访问的方法,根据拦截的数据操作类型执行不一样的处理,主要流程如下:步骤s603,获取数据访问的mappername(mappername对应于表名)、方法名methodname和传入的入参。其中,终端根据mappername映射得到表名。由此,终端可以获取数据访问的方法名和表名。步骤s604,查询jvm级缓存数据,判断该表mappername是否在强制加锁定义表sys_manlock_def中配置过,即根据表名判断缓存的强制加锁定义表是否有该表配置。步骤s605,该表mappername在强制加锁定义表中已配置,则根据不同的方法名执行不同的操作;操作包括插入/加锁/更新。步骤s606,如果方法名为加锁操作(selectpkwithlock方法:selectforupdate)或者插入操作(insertxxx方法),则操作数据构造为data=domainname+pk插入当前事务已加锁数据缓存区。也就是说,此时终端将操作数据写入当前事务的已加锁数据缓存区,数据通过表定义对应的domainname+主键pk(或通过“_”连接的复合主键)的形式表示,具体的主键值通过强制加锁定义表配置的primary_key和拦截器获取的入参得到。其中,插入操作代表该数据是在当前事务中首次建立的,数据库事务的隔离性决定了事务提交前该数据不会被其他事务读取并且更新到,为了校验规则的统一性,对本层事务中先插入后更新的操作,也按照强制锁检测的流程处理,将插入操作视同加锁操作把用domainname+pk表示的数据放入本层事务的已加锁数据缓存区;步骤s607,如果方法名为更新(updatexxx)操作,通过和插入数据同样的数据表示形式组装操作的数据(表定义对应的domainname+主键pk或复合主键),判断当前事务已加锁数据缓存区是否存在data=domainname+pk表示的操作数据。也就是说,此时终端查找当前事务已加锁缓存区是否已有该数据。在数据更新操作中,若当前事务已加锁缓存区中已有domainname+pk表示的操作数据,说明操作的数据已在当前事务中执行过加锁处理,则强制加锁检查成功,跳转到步骤s608执行后续数据访问流程,如执行数据库访问及其他流程。需要说明的是,前述的终端确定表mappername在强制加锁定义表中未配置,则直接跳过强制加锁检查,跳转到步骤s608执行后续数据访问流程,执行数据库访问及其他流程。在数据更新操作中,若当前事务已加锁缓存区中不存在domainname+pk表示的操作数据,说明操作的数据在当前事务中未执行过加锁处理,存在并发更新共享数据的风险,则跳转到步骤s609基于异常处理方式对数据进行处理。步骤s610,根据强制加锁定义表中的异常处理方式不中断流程,只打印告警日志;进一步跳转到步骤s608执行后续数据访问流程。步骤s611,根据强制加锁定义表中的异常处理方式报错中断,事务失败回滚。步骤s612,在步骤s608执行后续数据访问流程之后,确定事务成功。步骤s613,确定事务成功或者事务失败,则触发强制加锁检测适配器,移除本层事务缓存区。步骤s614,事务结束。本申请提供的数据加锁检测方法,具有如下有益效果,业务代码无侵入性。强制加锁检测的机制与业务逻辑完全解耦,业务层开发人员只需要调用mybatismapper读写数据库即可。实现特定数据表的强制加锁检测,通过强制开发人员在同一个事务中更新数据之前必须加锁的策略,能够从源头上避免问题从而保证金融数据的安全性。实现特定数据表的动态配置,包括检测异常的处理方式。可根据实际场景灵活配置需要做加锁检测的数据表,且调整时仅仅需要调整配置即可,无需停机做任何代码上的修改。业务代码无侵入性。强制加锁检测的机制与业务逻辑完全解耦,业务层开发人员只需要调用mybatismapper读写数据库即可。支持嵌套事务的强制加锁检查。下面继续说明本申请实施例提供的数据加锁检测装置154实施为软件模块的示例性结构,在一些实施例中,如图1所示,存储在存储器150的数据加锁检测装置154中的软件模块可以是终端100中的数据加锁检测装置,包括:获取模块1541,用于若开启事务,获取所述事务对应的数据库访问接口的第一方法名和第一表名;处理模块1542,用于若保存的强制加锁定义表包括所述第一表名,且所述第一方法名表征对所述事务关联的数据执行更新操作,从已加锁数据缓存区中所述事务对应的缓存区查找所述数据,得到检测结果;所述处理模块1542,还用于若所述检测结果表征所述事务对应的缓存区不存在所述数据,从所述强制加锁定义表中获取与所述第一表名对应的处理策略;所述处理模块1542,还用于基于所述处理策略,对所述数据进行处理。在一些实施例中,所述处理模块1542,还用于禁止对所述数据执行更新操作,并确定所述事务处理失败在一些实施例中,所述处理模块1542,还用于生成提示信息并输出所述提示信息;所述提示信息用于提示在所述事务中未对所述数据执行过加锁处理;对所述数据执行更新操作,并确定所述事务处理成功。在一些实施例中,所述处理模块1542,还用于若所述强制加锁定义表包括所述第一表名,且所述第一方法名表征对所述事务关联的数据执行插入操作或查询加锁操作,将所述数据写入所述事务对应的缓存区;对所述事务对应的缓存区中的所述数据执行读写操作,并确定所述事务处理成功。在一些实施例中,获取模块1541,还用于获取所述数据库访问接口的第二方法名和第二表名;所述处理模块1542,还用于若所述强制加锁定义表包括所述第二表名,且所述第二方法名表征对所述数据执行更新操作,从所述事务对应的缓存区查找所述数据,得到表征所述事务对应的缓存区存在所述数据的检测结果;对所述数据执行更新操作,并确定所述事务处理成功。在一些实施例中,获取模块1541,还用于获取触发事件,所述触发事件用于更新所述强制加锁定义表中的表名;其中,所述强制加锁定义表中的表名包括所述第一表名;所述处理模块1542,还用于更新所述强制加锁定义表中的表名;加载所述强制加锁定义表至java虚拟机内存中。在一些实施例中,所述事务为主事务,所述主事务嵌套至少一个子事务,所述主事务和任一所述子事务在所述已加锁数据缓存区中具有独立的缓存区。本申请提供的数据加锁检测装置,通过若开启事务,获取所述事务对应的数据库访问接口的第一方法名和第一表名;若保存的强制加锁定义表包括所述第一表名,且所述第一方法名表征对所述事务关联的数据执行更新操作,从已加锁数据缓存区中所述事务对应的缓存区查找所述数据,得到检测结果;若所述检测结果表征所述事务对应的缓存区不存在所述数据,从所述强制加锁定义表中获取与所述第一表名对应的处理策略;基于所述处理策略,对所述数据进行处理;如此在更新数据之前实现精确的加锁检测,实现有效检测出并发问题,并且当检测出未加锁时,基于表名对应的处理策略对数据进行相应的处理,提高检测加锁检测效率和检测准确性,避免并发问题的出现,对为加锁现象进行合理处理,提高数据的安全性。需要说明的是,本申请实施例装置的描述,与上述方法实施例的描述是类似的,具有同方法实施例相似的有益效果,因此不做赘述。对于本装置实施例中未披露的技术细节,请参照本申请方法实施例的描述而理解。本申请实施例提供一种存储有可执行指令的存储介质,其中存储有可执行指令,当可执行指令被处理器执行时,将引起处理器执行本申请实施例提供的方法,例如,如图3、5-7示出的方法。在一些实施例中,存储介质可以是计算机可读存储介质,例如,铁电存储器(fram,ferromagneticrandomaccessmemory)、只读存储器(rom,readonlymemory)、可编程只读存储器(prom,programmablereadonlymemory)、可擦除可编程只读存储器(eprom,erasableprogrammablereadonlymemory)、带电可擦可编程只读存储器(eeprom,electricallyerasableprogrammablereadonlymemory)、闪存、磁表面存储器、光盘、或光盘只读存储器(cd-rom,compactdisk-readonlymemory)等存储器;也可以是包括上述存储器之一或任意组合的各种设备。在一些实施例中,可执行指令可以采用程序、软件、软件模块、脚本或代码的形式,按任意形式的编程语言(包括编译或解释语言,或者声明性或过程性语言)来编写,并且其可按任意形式部署,包括被部署为独立的程序或者被部署为模块、组件、子例程或者适合在计算环境中使用的其它单元。作为示例,可执行指令可以但不一定对应于文件系统中的文件,可以可被存储在保存其它程序或数据的文件的一部分,例如,存储在超文本标记语言(超文本标记语言,hypertextmarkuplanguage)文档中的一个或多个脚本中,存储在专用于所讨论的程序的单个文件中,或者,存储在多个协同文件(例如,存储一个或多个模块、子程序或代码部分的文件)中。作为示例,可执行指令可被部署为在一个计算设备上执行,或者在位于一个地点的多个计算设备上执行,又或者,在分布在多个地点且通过通信网络互连的多个计算设备上执行。以上所述,仅为本申请的实施例而已,并非用于限定本申请的保护范围。凡在本申请的精神和范围之内所作的任何修改、等同替换和改进等,均包含在本申请的保护范围之内。当前第1页12
当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1