在现代计算机系统中,数据库是必不可少的一部分,它可以为许多业务和应用程序提供数据存储和管理的功能。但是,在多个用户同时访问数据库时,会面临着数据的并发性问题,也就是说,多个用户同时试图读取或修改同一条数据时,可能会发生冲突,导致数据的不一致性。
数据库系统通过锁机制来保证数据并发操作的正确性。其中,行锁是最常用的一种锁机制。行锁可以保证多个用户对同一表中的不同数据行进行并发操作时,彼此不会产生冲突,从而保证数据的完整性和一致性。本文将深入探讨如何正确使用行锁进行数据操作,以及行锁的性能优化。
一、行锁的基础知识
1. 行锁的类型
行锁分为共享锁(Shared Lock)和排他锁(Exclusive Lock)两种类型。
共享锁(也称读锁):多个事务可以同时持有一个共享锁,用于读取操作。共享锁和共享锁是兼容的,即多个事务可以同时持有一个共享锁而不干扰彼此。
排他锁(也称写锁):只允许一个事务持有排他锁,用于写入操作。排他锁和排他锁是互斥的,即在一个事务持有排他锁时,另一个事务不能获得相同的锁,因为它们会相互干扰。
2. 行锁的范围
行锁是针对某一行数据进行锁定,锁定的范围包括“访问”和“修改”两个方面。
访问锁:在读取数据时,对数据行进行锁定,防止其他事务修改该行数据,但不阻止其他事务读取同一行数据。
修改锁:在修改数据时,对数据行进行锁定,防止其他事务访问和修改该行数据。
3. 行锁的粒度
行锁的粒度有两种,分别是表级别锁和行级别锁。
表级别锁:指对整张表进行锁定,是一种粗粒度的锁,通常用于执行大型批处理等操作,而非在线事务处理。
行级别锁:指对表中指定行数据进行锁定,是一种细粒度的锁,通常用于在线事务处理。
二、正确使用行锁的实践
1. 事务的基础知识
行锁必须与事务一起使用,因为只有在事务中才能有效地使用行锁。事务是对数据库操作的逻辑单元,将多个操作视为一个整体,并保证这些操作要么全部成功,要么全部失败。事务中的操作必须满足ACID原则,即原子性、一致性、隔离性和持久性。
2. 使用锁定语句进行锁定
在事务中,可以使用锁定语句来锁定表中的数据行。例如,在MySQL中可以使用以下语句锁定数据行:
SELECT * from table_name WHERE id = ? For UPDATE;
其中,FOR UPDATE是锁定语句,它会对查询结果中的数据行进行排他锁定,防止其他事务修改该行数据。
3. 使用索引锁定数据行
在事务中,使用索引可以加快数据访问的速度,也可以较为方便地对数据行进行锁定。例如,在MySQL中可以使用以下语句锁定索引:
SELECT * FROM table_name WHERE id = ? FOR UPDATE;
其中,使用了索引id进行数据查找,FOR UPDATE语句同样是锁定语句,它会对查询结果中的数据行进行排他锁定,防止其他事务修改该行数据。
4. 锁定范围的控制
在事务中,锁定范围的控制也是非常重要的。如果锁定范围太小,会导致并发操作时仍然存在冲突的可能;如果锁定范围太大,会导致操作的效率低下,甚至会引发死锁等问题。
因此,在实践中,需要根据具体情况来控制锁定范围。一般来说,如果是对单个数据行进行读取和修改操作,那么行级别锁是更好的选择;如果是批量操作和大量数据查询,那么表级别锁可能更适合。
5. 避免使用强制调度锁定语句
强制调度锁定语句可以强制一个事务中的某些操作等待其他事务完成,再进行自己的操作。但是,这种语句的使用会导致数据库性能下降,甚至会引发死锁等问题。
因此,在实践中,应该尽量避免使用强制调度锁定语句。替代方案包括使用乐观锁、悲观锁等技术,来保证数据操作的正确性。
三、行锁的性能优化
1. 使用并发控制算法
并发控制算法是一种优化锁机制,在多用户并发访问时,可以提高数据库的性能和吞吐量。常见的并发控制算法包括两阶段封锁(2PL)和多版本并发控制(MVCC)等。
其中,2PL算法是目前最为主流的并发控制算法之一,它将事务分为两个阶段,之一个阶段是加锁阶段,在这个阶段中,事务需要获取它需要访问的所有数据的行级别锁;第二个阶段是解锁阶段,在这个阶段中,事务会按照相反的顺序释放它所持有的全部锁。
2. 适当控制锁的请求频率
在实际数据库操作中,锁的请求次数是非常频繁的,如果不加以控制,会导致性能下降、死锁等问题。因此,适当控制锁的请求频率是一种有效的性能优化方法。
在实践中,可以采用两种方法来控制锁的请求频率。一种方法是使用任务分离技术,将数据库操作分成小的任务,每次仅处理一个任务,从而降低锁请求的频率。另一种方法是使用持久化技术,将数据读入内存,使锁申请和释放的开销减少。
3. 合理使用锁定范围
锁定范围的大小会直接影响到数据库操作的性能。如果锁定范围太小,会导致其他用户等待太久;如果锁定范围太大,则会占用大量系统资源,影响整体性能。
因此,在实践中,需要根据具体情况合理使用锁定范围。一般来说,对于单个数据行的读取和修改操作,行级别锁是更好的选择;对于大规模的批处理和数据查询,表级别锁可能更适合。

四、结论
行锁是数据库中实现并发控制的重要手段,它可以保证多用户对同一表中的不同数据行进行并发操作时,彼此不会产生冲突,从而保证数据的完整性和一致性。在实践中,正确使用行锁是非常重要的,需要结合事务、索引、锁定范围等多种因素进行综合考虑。同时,优化行锁的性能是一个不断追求的过程,需要不断尝试新的并发控制算法、控制锁的请求频率、合理使用锁定范围等方法。
相关问题拓展阅读:
MyBatisPlus 分页插件和数据库行锁的几点思考
前段时间跟踪 MyBatis 源码,分析 MyBatis 的分页查询结果后,发现传入的 IPage 参数结果已经包含了查询数据了,以为分页查询语句的关键在于之一个入参必须是 IPage ,而不需要返回值了呢。
昨天发现不是这么回事儿,本文再回顾一下 MyBatis 分页插件的用法及三个发现:
本文讲解答上面三个问题。简败
之一步
,设置分页查询插件。
第二步
,编写分页查询 DAO 方法:
该方法执行完成后,查询数据会存储到 iPage 参数中,可以直接获取方法返回值。值得注意的是,这个方法必须有返回值。
我最初以为,查询结果都存储到参数中了,是不是方法定义中可以不用返回值了。昨天编码时就随手写成这样了:
结果,执行报 了 SQL 异常:
纳闷了半天,这分页查询怎么就变成了单条查询了呢?对比旧项目代码,还原分页查询方法,正常了。
结论
:MyBatisPlus 分页方法返回值必须是 IPage ,不能为 void 。
以往页面的分页查询,每页数据都很少,没有发现这个问题。
这次实现的是一个批处理任务,一次处理的数据要尽量大。 iPage 分页参数拦基颤 size 初始设置为 1000,发现日志输出的记录数总是 500 条 ,分页参数失效了,为何呢?
使用客户端连接数据库查询,一次能取 1000 条,而 MyBatisPlus 分页查询,这个 500 条是谁控制的呢?能否修改呢?
答案是
: PaginationInterceptor 限制了单页条数 500,如果需要,可以这样修改:
业务要求某个任务设计成多机、并行任务,且要保证数据一致。Quartz 框架的分布式任务只能保证任务被一个节点执行,不符合需求,Spring Task 倒是可以实现。
所以问题就变成分布式锁的设计了,参考 Quartz 的集群方案中的锁机制,实现基于数据库行锁的锁。
没测试基于行锁的分布式锁之前,我以为某个事务执行 select for update 之后,其他事务再对相同记录执行该操作的话,应该会报异常,导致锁获取失败。
测试发现,某条记录被锋搭锁定之后,交互流程大概是这样的:
结论
:数据库记录的行锁是排他的,其他事务会阻塞等待。
辛丑年腊月二十八,上述就是今年最后一个工作日的总结。
收拾收拾,准备迎接农历新年!
数据库加行锁的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于数据库加行锁,深入了解数据库:如何正确使用行锁进行数据操作?,MyBatisPlus 分页插件和数据库行锁的几点思考的信息别忘了在本站进行查找喔。
香港服务器首选树叶云,2H2G首月10元开通。树叶云(shuyeidc.com)提供简单好用,价格厚道的香港/美国云 服务器 和独立服务器。IDC+ISP+ICP资质。ARIN和APNIC会员。成熟技术团队15年行业经验。
详解Oracle DELETE和TRUNCATE 的区别
展开全部语法delete from aa truncate table aa 区别 from后面可以写条件,truncate不可以。 from记录是一条条删的,所删除的每行记录都会进日志,而truncate一次性删掉整个页,因此日至里面只记录页释放,简言之,delete from更新日志,truncate基本不,所用的事务日志空间较少。 from删空表后,会保留一个空的页,truncate在表中不会留有任何页。 4.当使用行锁执行 DELETE 语句时,将锁定表中各行以便删除。 truncate始终锁定表和页,而不是锁定各行。 5.如果有identity产生的自增id列,delete from后仍然从上次的数开始增加,即种子不变,而truncate后,种子会恢复初始。 不会触发delete的触发器,因为truncate操作不记录各个行删除。 总结和 delete只删除数据不删除表的结构(定义) drop语句将删除表的结构被依赖的约束(constrain),触发器(trigger),索引(index); 依赖于该表的存储过程/函数将保留,但是变为invalid状态。 语句是dml,这个操作会放到rollback segement中,事务提交之后才生效;如果有相应的trigger,执行的时候将被触发truncate,drop是ddl, 操作立即生效,原数据不放到rollback segment中,不能回滚. 操作不触发trigger。 语句不影响表所占用的extent, 高水线(high watermark)保持原位置不动 显然drop语句将表所占用的空间全部释放 truncate 语句缺省情况下见空间释放到 minextents个 extent,除非使用reuse storage; truncate会将高水线复位(回到最开始)。 4.速度,一般来说: drop> truncate > delete。 5.安全性:小心使用drop 和truncate,尤其没有备份的时候.否则哭都来不及。 6.使用上,想删除部分数据行用delete,注意带上where子句. 回滚段要足够大. 想删除表,当然用drop 想保留表而将所有数据删除. 如果和事务无关,用truncate即可. 如果和事务有关,或者想触发trigger,还是用delete如果是整理表内部的碎片,可以用truncate跟上reuse stroage,再重新导入/插入数据。
delete、truncate的相同点不同点是什么
相同点:都是删除数据,truncate效果等同于不带where的delete不同点:delete删除时要详细记录事务日志,而truncate只记录truncate操作,不记录具体数据操作,所以truncate操作要比delete快得多(ps:一旦用了truncate很难进行数据库恢复,慎用);恩。 。 自己总结的还是不好啊,直接贴联机丛书的吧与 DELETE 语句相比,TRUNCATE TABLE 具有以下优点:所用的事务日志空间较少。 DELETE 语句每次删除一行,并在事务日志中为所删除的每行记录一个项。 TRUNCATE TABLE 通过释放用于存储表数据的数据页来删除数据,并且在事务日志中只记录页释放。 使用的锁通常较少。 当使用行锁执行 DELETE 语句时,将锁定表中各行以便删除。 TRUNCATE TABLE 始终锁定表和页,而不是锁定各行。 如无例外,在表中不会留有任何页。 执行 DELETE 语句后,表仍会包含空页。 例如,必须至少使用一个排他 (LCK_M_X) 表锁,才能释放堆中的空表。 如果执行删除操作时没有使用表锁,表(堆)中将包含许多空页。 对于索引,删除操作会留下一些空页,尽管这些页会通过后台清除进程迅速释放。 TRUNCATE TABLE 删除表中的所有行,但表结构及其列、约束、索引等保持不变。 若要删除表定义及其数据,请使用 DROP TABLE 语句。 如果表包含标识列,该列的计数器重置为该列定义的种子值。 如果未定义种子,则使用默认值 1。 若要保留标识计数器,请使用 DELETE。 限制不能对以下表使用 TRUNCATE TABLE:由 FOREIGN KEY 约束引用的表。 (您可以截断具有引用自身的外键的表。 )参与索引视图的表。 通过使用事务复制或合并复制发布的表。 对于具有以上一个或多个特征的表,请使用 DELETE 语句。 TRUNCATE TABLE 不能激活触发器,因为该操作不记录各个行删除
asp和jsp有什么区别吗?
总的来讲,JavaSever PagesTM(JSP)和 微软的Active Sever Pages(ASP)在技术方面有许多相似之处。 两者都是为基于WEB应用实现动态交互网页制作提供的技术环境支持。 同等程度上来讲,两者都能够为程序开发人员提供实现应用程序的编制与自带组件设计网页从逻辑上分离的技术。 而且两者都能够替代CGI使网站建设与发展变的较为简单与快捷。 尽管JavaSever Pages 技术和微软的Active Sever Pages在许多方面都有相似的,但仍然存在很多不同之处,其中最本质上的区别在于:两者是来源于不同的技术规范组织,其实现的基础:Web服务器平台要求不相同。 一、 JSP 技术:开放的技术 JSP和ASP技术明显的不同点:开发人员在对两者各自软件体系设计的深入了解的方式不同。 JSP技术基于平台和服务器的互相独立,输入支持来自广泛的,专门的,各种工具包,服务器的组件和数据库产品开发商所提供。 相比之下,ASP技术主要依赖微软的技术支持。 1、 平台和服务器的独立性 JSP技术依附于一次写入,之后,可以运行在任何具有符合JavaTM语法结构的环境。 取而代之过去依附于单一平台或开发商,JSP技术能够运行在任何WEB服务器上并且支持来自多家开发商提供的各种各样工具包。 由于ASP是基于Activex控件技术提供客户端和服务器端的开发组件,因此ASP技术基本上是局限于微软的操作系统平台之上。 ASP主要工作环境是微软的IIS应用程序结构,又因Activex对象具有平台特性,所以ASP技术不能很容易地实现在跨平台的WEB服务器的工作。 尽管ASP技术通过第三方提供的产品能够得到组件和服务实现跨平台的应用程序,但是Activex对象必须事先放置于所选择的平台中。 2、 开放的开发过程,开放的原代码 SUN应用JAVA社团性过程开发JSP技术。 自从1995年,SUN已经用这种开放过程方法同国际JAVA组织合作开发和修改了JAVA技术与规范。 针对JSP的产品,SUN授权了工具提供商(如Macromedia),结盟公司(如Apache,Netscape),最终用户,协作商及其他。 最近,SUN将最新版本的JSP和JavaTM Servlet(JSP 1.1,JAVA SERVLET 2.2)的原代码发放给Apache,以求JSP与Apache紧密的相互发展。 Apache,SUN和许多其他的公司及个人公开成立一个健壮的咨询机构以便任何公司和个人都能免费取得信息。 (详见:) JSP应用程序界面(API)毫无疑问已经取得成功,并将随JAVA组织不断开放扩大继续完善。 相反,ASP技术仅依靠微软本身的推动,其发展是建立在独占的,封闭的开发过程基础之上。 ASP技术 JSP技术 WEB服务器 微软的IIS或个人WEB服务器 任何WEB服务器包括Apache,Netscape,和IIS 操作系统平台 微软的视窗系统 绝大多数的流行平台,包括solaris操作系统,微软的视窗系统,MAC OS,Linux,及其他UNIX系列平台产品 跨平台访问 需要第三方ASP的引入产品 支持WEB信息机构环境中不同系列的计算机群即保证用户在当前软硬件及人力资源上的投资完全兼容,JSP技术提供灵活,开放选择:可以使用各种各样的工具提供商提供的工具,高度体现工业化标准输入与配置 3、从开发人员的角度来看:ASP和JSP技术都能使开发者实现通过点击网页中的组件制作交互式的,动态的内容和应用程序的WEB站点。 ASP仅支持组件对象模型COM,而JSP技术提供的组件都是基于JavabeansTM技术或JSP标签库。 由此可以看出两者虽有相同之处,但其区别是很明显的。 1) JSP标签可扩充性 尽管ASP和JSP都使用标签与脚本技术来制作动态WEB网页,JSP技术能够使开发者扩展JSP标签得以应用,JSP开发者能定制标签库,所以网页制作者充分利用与XML兼容的标签技术强大的功能,大大减少对脚本语言的依赖。 由于定制标签技术,使网页制作者降低了制作网页和向多个网页扩充关键功能的复杂程度。 2) JSP跨平台的可重用性 JSP的开发人员在开发过程中一直关注可重用性。 JSP组件(企业JavabeansTM,Javabeans,或定制的JSP标签)都是跨平台可重用的。 企业Javabeans组件可以访问传统的数据库,并能以分布式系统模式工作于UNIX和WINDOWS平台。 JSP技术的标签可扩充功能为开发人员提供简便的,与XML兼容的接口即共享网页的打包功能使其完全的工业标准化。 这种基于组件的模式很有效提高应用程序的开发效率,因为这种模式能够使开发人员利用快捷的子组件快速创建模板应用程序,然后再整合一些附加功能以后便可使用。 象这样有效的方法在JSP中无处不在,并可将其打包成一个Javabean或一个工业标准化的Javabean组件。 二、 JAVA的优越性 JSP技术是用JAVA语言作为脚本语言的,而ASP网页使用微软的VBScrip或Jscrip。 JAVA是成熟的,强大的,易扩充的编程语言,远优于基于BASIC的脚本语言。 如:JAVA的可执行性优于VBScript或Jscript语言。 因为它们利用JAVA技术并且都被编译为JAVA Servlets,JSP网页为整个服务器端的JAVA库单元提供了一个接口来服务于HTTP的应用程序。 JAVA使开发人员的工作在其他方面也变的一样容易,简单。 例如,当ASP应用程序在WINDOWS NT系统被怀疑可能会崩溃时,JAVA能有效的防止系统的崩溃。 JAVA语言通过提供防止内存的泄漏的方法,在内存管理方面也能大显身手。 加之,JSP为应用提供了健壮的意外事件处理机制。 1、 易于维护性 基于JSP技术的应用程序比基于ASP的应用程序易于维护和管理。 脚本语言都能很好服务于小的应用程序,但不能适应大型的,复杂的应用程序。 因为,JAVA是结构化的,它比较容易创建和维护庞大的,组件化的应用程序。 JSP突出的组件技术使修改内容而不影响逻辑或修改逻辑而不影响内容变得很容易实现。 企业级的Javabeans结构整合了企业逻辑,例如数据库的访问,安全,事务完整性,及独立性即独立于应用程序。 因为JSP技术是一种开放的,跨平台的结构,因此,WEB服务器,平台,及其他的组件能很容易升级或切换,且不会影响JSP基本的应用程序。 这一特点使JSP能够适用现实世界的各种WEB应用程序不断的变化和发展。 ASP技术 JSP技术 可重用,跨平台组件 没有JAVABEANS 企业级JAVABEANS,定制JSP标签 安全:防范系统崩溃 没有 有 内存泄露保护 没有 有 脚本语言 VBSCRIPT,JSCRIPT JAVA 定制标签 没有 有 2、企业产品的多样性 JAVA2平台即企业版(J2EE)是适用于多企业应用程序的JAVA结构,作为J2EE的部分,JSP网页可访问所有J2EE的组件,包括Javabeans,企业级Javabeans及JAVA Servlets。 JSP网页都能完全编译成为Servlets,所以它们都享有灵活性的特点和为服务器端JAVA应用程序。 J2EE平台内容不仅包括管理复杂的企业应用程序而且包括事务管理技术和Pooling资源管理技术。 JSP网页可以访问标准的J2EE服务,包括: ? JAVA名称和目录界面API ? JDBCTM API(与关联的数据库通讯) ? JavaMailTM(支持基于JAVA邮件和消息应用程序的类) ? JAVATM 消息服务 通过J2EE,JSP网页能够用许多方式同企业系统交互访问。 J2EE支持两种CORBA规范的技术:JAVA IDL和RMI-IIOP。 在企业级JAVABEANS技术支持下,JSP网页通过运用高级的,对象映射的方式访问数据库。 最终,因为JSP技术是基于JAVA的开放性过程的产品,因此它能够广泛支持不同提供商提供的工具,WEB服务器和应用程序的服务,这样能够使用户选择最佳的开发方法,选择最适应他们的应用程序开发的工具包,同时,有效地保护用户在代码和人员培训上的投资。 ASP技术 JSP技术 兼容传统的数据库 可以(COM) 可以(用JDBC API) 集成数据源的能力 能工作在任何符合ODBC规范的数据库 能工作在任何符合ODBC规范的数据库,而且能访问符合JDBC技术规范数据库 组件 COM组件 JAVABEANS,企业级JAVABEANS或扩展的JSP标签 扩展工具支持
发表评论