数据库锁表的分析与解决
上面介绍了内存溢出的原因和处理方法,下面再介绍一下数据库锁表及阻塞的原因和处理办法。
数据库和操作系统一样,是一个多用户使用的共享资源。当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据的情况。若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性。加锁是实现数据库并发控制的一个非常重要的技术。在实际应用中经常会遇到的与锁相关的异常情况,当两个事务需要一组有冲突的锁,而不能将事务继续下去的话,就会出现死锁,严重影响应用的正常执行。
在数据库中有两种基本的锁类型:排它锁(Exclusive Locks,即X锁)和共享锁(Share Locks,即S锁)。当数据对象被加上排它锁时,其他的事务不能对它读取和修改。加了共享锁的数据对象可以被其他事务读取,但不能修改。数据库利用这两种基本的锁类型来对数据库的事务进行并发控制。
死锁的第一种情况
一个用户A 访问表A(锁住了表A),然后又访问表B;另一个用户B 访问表B(锁住了表B),然后企图访问表A;这时用户A由于用户B已经锁住表B,它必须等待用户B释放表B才能继续,同样用户B要等用户A释放表A才能继续,这就死锁就产生了。
解决方法:
这种死锁比较常见,是由于程序的BUG产生的,除了调整的程序的逻辑没有其它的办法。仔细分析程序的逻辑,对于数据库的多表操作时,尽量按照相同的顺序进行处理,尽量避免同时锁定两个资源,如操作A和B两张表时,总是按先A后B的顺序处理, 必须同时锁定两个资源时,要保证在任何时刻都应该按照相同的顺序来锁定资源。
死锁的第二种情况
用户A查询一条纪录,然后修改该条纪录;这时用户B修改该条纪录,这时用户A的事务里锁的性质由查询的共享锁企图上升到独占锁,而用户B里的独占锁由于A有共享锁存在所以必须等A释放掉共享锁,而A由于B的独占锁而无法上升的独占锁也就不可能释放共享锁,于是出现了死锁。这种死锁比较隐蔽,但在稍大点的项目中经常发生。如在某项目中,页面上的按钮点击后,没有使按钮立刻失效,使得用户会多次快速点击同一按钮,这样同一段代码对数据库同一条记录进行多次操作,很容易就出现这种死锁的情况。
解决方法:
1、对于按钮等控件,点击后使其立刻失效,不让用户重复点击,避免对同时对同一条记录操作。
2、使用乐观锁进行控制。乐观锁大多是基于数据版本(Version)记录机制实现。即为数据增加一个版本标识,在基于数据库表的版本解决方案中,一般是通过为数据库表增加一个“version”字段来实现。读取出数据时,将此版本号一同读出,之后更新时,对此版本号加一。此时,将提交数据的版本数据与数据库表对应记录的当前版本信息进行比对,如果提交的数据版本号大于数据库表当前版本号,则予以更新,否则认为是过期数据。乐观锁机制避免了长事务中的数据库加锁开销(用户A和用户B操作过程中,都没有对数据库数据加锁),大大提升了大并发量下的系统整体性能表现。Hibernate 在其数据访问引擎中内置了乐观锁实现。需要注意的是,由于乐观锁机制是在我们的系统中实现,来自外部系统的用户更新操作不受我们系统的控制,因此可能会造成脏数据被更新到数据库中。
3、使用悲观锁进行控制。悲观锁大多数情况下依靠数据库的锁机制实现,如Oracle的Select … for update语句,以保证操作最大程度的独占性。但随之而来的就是数据库性能的大量开销,特别是对长事务而言,这样的开销往往无法承受。如一个金融系统,当某个操作员读取用户的数据,并在读出的用户数据的基础上进行修改时(如更改用户账户余额),如果采用悲观锁机制,也就意味着整个操作过程中(从操作员读出数据、开始修改直至提交修改结果的全过程,甚至还包括操作员中途去煮咖啡的时间),数据库记录始终处于加锁状态,可以想见,如果面对成百上千个并发,这样的情况将导致灾难性的后果。所以,采用悲观锁进行控制时一定要考虑清楚。
死锁的第三种情况
如果在事务中执行了一条不满足条件的update语句,则执行全表扫描,把行级锁上升为表级锁,多个这样的事务执行后,就很容易产生死锁和阻塞。类似的情况还有当表中的数据量非常庞大而索引建的过少或不合适的时候,使得经常发生全表扫描,最终应用系统会越来越慢,最终发生阻塞或死锁。
解决方法:
SQL语句中不要使用太复杂的关联多表的查询;使用“执行计划”对SQL语句进行分析,对于有全表扫描的SQL语句,建立相应的索引进行优化。
5.小结
总体上来说,产生内存溢出与锁表都是由于代码写的不好造成的,因此提高代码的质量是最根本的解决办法。有的人认为先把功能实现,有BUG时再在测试阶段进行修正,这种想法是错误的。正如一件产品的质量是在生产制造的过程中决定的,而不是质量检测时决定的,软件的质量在设计与编码阶段就已经决定了,测试只是对软件质量的一个验证,因为测试不可能找出软件中所有的BUG。
分享到:
相关推荐
Informix 数据库锁表问题解决方案 在 Informix 数据库中,锁表问题是一个常见的错误,会导致系统性能下降和数据不一致。锁表问题的解决需要对数据库进行深入的分析和诊断。本文将讨论 Informix 数据库锁表问题的...
### 数据库锁表问题解决方法 #### 一、问题背景 在进行数据库操作时,比如对数据表进行插入(INSERT)、更新(UPDATE)或删除(DELETE)操作,或者是添加主键(PRIMARY KEY)或索引(INDEX)时,可能会遇到ORA-...
Oracle 数据库锁是确保数据完整性、一致性以及并发操作的关键机制。在Oracle中,锁主要分为两类:数据锁(DML锁)和字典锁。字典锁主要用于内部管理,特别是语法分析和DDL操作,用户无法直接控制。而数据锁则是我们...
本人原创文章,分要的多点. 内存溢出与数据库锁表的问题,可以说是开发人员的噩梦,一般的程序...本文以笔者开发和支持的多个项目为例,与大家分享在开发过程中遇到的Java内存溢出和数据库锁表的检测和处理解决过程。
【数据库安全事务与锁】 数据库安全事务与锁是数据库管理系统中的关键概念,它们确保了多用户环境下数据的一致性和完整性。在SQL Server 2000中,事务和锁机制对于保证数据库系统的并发操作和数据安全性至关重要。 ...
总之,一次长事务导致数据库锁等待超时问题,是数据库管理中的常见挑战。通过理解事务、锁机制和超时原理,结合有效的诊断方法和解决策略,我们可以有效地避免和解决此类问题,确保数据库系统的稳定运行。
数据库加锁与性能分析是数据库...总的来说,数据库加锁与性能分析是数据库管理员和开发者的必备知识,理解并熟练运用各种锁机制和事务处理策略,能够在保证数据一致性的同时,有效提升系统的并发处理能力和整体性能。
HIS系统SQL Server数据库死锁问题的分析与解决 SQL Server数据库是HIS系统中非常重要的一部分,负责存储和管理大量的医疗数据。然而,在实际应用中,SQL Server数据库可能会出现死锁问题,导致系统性能下降, thậm...
数据库锁主要用于解决并发控制问题,通过加锁来保证数据的一致性。根据锁的作用范围和粒度不同,可以分为多种类型: 1. **行级锁**:作用于单个记录或行上。 2. **表级锁**:作用于整个表上。 3. **页级锁**:作用...
总结来说,轻量数据挖掘方法在数据库锁表优化方面具有很大的潜力,通过建立神经网络预测器,可以自动调整锁表参数,减少锁冲突,提升系统整体的性能和事务处理能力。未来的研究将聚焦于进一步提高神经网络的性能,...
针对数据库锁表管理,使用基于轻量数据挖掘的优化方法,通过对性能数据的学习,建立一个能够根据锁表参数预测系统性能的神经网络预测器;在系统运行过程中,自我优化模块不断监控性能数据的变化,通过规则引擎选择...
本文将对 MS SQL Server 数据库锁技术进行详细的研究和分析。 数据库锁的概念 数据库锁是一种软件机制,用于指示用户已经占用了某种资源,从而防止其他用户的数据修改或导致数据库的数据非完整性和非一致性。...
在Oracle、MySQL和DB2等数据库系统中,锁表的SESSION处理是解决并发操作时出现的锁定问题的重要方法。本篇文章将深入探讨锁表的SESSION处理方法,包括如何查询被锁住的SESSION信息,理解各种锁类型以及如何结束导致...
并发访问ORACLE数据库的数据死锁分析和解决措施 Oracle数据库是一个关系型数据库管理系统,广泛应用于各种行业领域。在实际应用中,高并发访问数据库可能会导致数据死锁问题,本文将对数据死锁分析和解决措施进行...
### 修复SQL数据库MDF表出错——解决速达软件不能修复和不能备份账套问题 #### 一、问题背景及重要性 在使用基于SQL Server数据库的企业管理软件(如速达ERP)的过程中,可能会遇到数据库表损坏的问题,具体表现为...
数据库锁和索引是数据库管理系统中的关键概念,它们对于确保数据的一致性、完整性和并发控制至关重要。在本次实验中,我们将深入理解这两个概念,并通过实际操作来掌握它们的运用。 首先,我们要了解数据库的锁机制...
SQL Server提供了如`sys.dm_tran_locks`动态管理视图来监控当前系统的锁情况,通过分析这些信息,可以诊断和解决锁相关的问题。对于源码级别的理解,虽然SQL Server的源码并未公开,但微软提供了大量的文档和SDK,...
#### 六、锁案例分析 以下是一个使用排它锁和共享锁的具体案例: **排它锁案例**: 1. 假设线程T1执行`SELECT * FROM goods_lock WHERE id = 1 FOR UPDATE;`。 2. T1获取排它锁,并对id为1的记录加锁。 3. 在T1...
### MySQL数据库优化与表设计详解 #### 一、数据库结构设计的重要性 在系统开发初期,一个合理且高效的数据库模型设计至关重要。它不仅能简化客户端和服务器端程序的开发及维护工作,还能显著提升系统运行时的性能...