c#+mysql锁_C#数据表加锁解锁
锁定数据库的⼀个表
SELECT * FROM table WITH (HOLDLOCK)
其他事务可以读取表,但不能更新删除
SELECT * FROM table WITH (TABLOCKX)
其他事务不能读取表,更新和删除
SELECT 语句中“加锁选项”的功能说明
SQL Server提供了强⼤⽽完备的锁机制来帮助实现数据库系统的并发性和⾼性能。⽤户既能使⽤SQL Server的缺省设置也可以在select 语句中使⽤“加锁选项”来实现预期的效果。 本⽂介绍了SELECT语句中的各项“加锁选项”以及相应的功能说明。
功能说明:
NOLOCK(不加锁)
此选项被选中时,SQL Server 在读取或修改数据时不加任何锁。 在这种情况下,⽤户有可能读取到未完成事务(Uncommited Transaction)或回滚(Roll Back)中的数据, 即所谓的“脏数据”。
HOLDLOCK(保持锁)
此选项被选中时,SQL Server 会将此共享锁保持⾄整个事务结束,⽽不会在途中释放。
UPDLOCK(修改锁)
此选项被选中时,SQL Server 在读取数据时使⽤修改锁来代替共享锁,并将此锁保持⾄整个事务或命令结束。使⽤此选项能够保证多个进程能同时读取数据但只有该进程能修改数据。
TABLOCK(表锁)
此选项被选中时,SQL Server 将在整个表上置共享锁直⾄该命令结束。 这个选项保证其他进程只能读取⽽不能修改数据。
PAGLOCK(页锁)
此选项为默认选项, 当被选中时,SQL Server 使⽤共享页锁。
TABLOCKX(排它表锁)
此选项被选中时,SQL Server 将在整个表上置排它锁直⾄该命令或事务结束。这将防⽌其他进程读取或修改表中的数据。
可参考:
[导读: 各种⼤型数据库所采⽤的锁的基本理论是⼀致的,但在具体实现上各有差别。SQL Server更强调由系统来管理锁。在⽤户有SQL 请求时,系统分析请求,⾃动在满⾜锁定条件和系统性能之间为数据库加上适当的锁,同时系统在运⾏期间常常⾃动进⾏优化处理,实⾏动态加锁。对于⼀般的⽤户⽽⾔,通过系统的⾃动锁定管理机制基本可以满⾜使⽤要求,但如果对数据安全、数据库完整性和⼀致性有特殊要求,就需要了解SQL Server的锁机制,掌握数据库锁定⽅法。]
锁是数据库中的⼀个⾮常重要的概念,它主要⽤于多⽤户环境下保证数据库完整性和⼀致性。 我们知道,多个⽤户能够同时操纵同⼀个数据库中的数据,会发⽣数据不⼀致现象。即如果没有锁定且多个⽤户同时访问⼀个数据库,则当他们的事务同时使⽤相同的数据时可能会发⽣问题。这些问题包括:丢失更新、脏读、不可重复读和幻觉读:mysql帮助文档
1.当两个或多个事务选择同⼀⾏,然后基于最初选定的值更新该⾏时,会发⽣丢失更新问题。每个事
务都不知道其它事务的存在。最后的更新将重写由其它事务所做的更新,这将导致数据丢失。例如,两个编辑⼈员制作了同⼀⽂档的电⼦复本。每个编辑⼈员独⽴地更改其复本,然后保存更改后的复本,这样就覆盖了原始⽂档。最后保存其更改复本的编辑⼈员覆盖了第⼀个编辑⼈员所做的更改。如果在第⼀个编辑⼈员完成之后第⼆个编辑⼈员才能进⾏更改,则可以避免该问题。
2. 脏读就是指当⼀个事务正在访问数据,并且对数据进⾏了修改,⽽这种修改还没有提交到数据库中,这时,另外⼀个事务也访问这个数据,然后使⽤了这个数据。因为这个数据是还没有提交的数据,那么另外⼀个事务读到的这个数据是脏数据,依据脏数据所做的操作可能是不正确的。例如,⼀个编辑⼈员正在更改电⼦⽂档。在更改过程中,另⼀个编辑⼈员复制了该⽂档(该复本包含到⽬前为⽌所做的全部更改)并将其分发给预期的⽤户。此后,第⼀个编辑⼈员认为⽬前所做的更改是错误的,于是删除了所做的编辑并保存了⽂档。分发给⽤户的⽂档包含不再存在的编辑内容,并且这些编辑内容应认为从未存在过。如果在第⼀个编辑⼈员确定最终更改前任何⼈都不能读取更改的⽂档,则可以避免该问题。
3.不可重复读是指在⼀个事务内,多次读同⼀数据。在这个事务还没有结束时,另外⼀个事务也访问该同⼀数据。那么,在第⼀个事务中的两次读数据之间,由于第⼆个事务的修改,那么第⼀个事务两次读到的的数据可能是不⼀样的。这样就发⽣了在⼀个事务内两次读到的数据是不⼀样的,因此称为是不可重复读。例如,⼀个编辑⼈员两次读取同⼀⽂档,但在两次读取之间,作者重写了该⽂档。当
编辑⼈员第⼆次读取⽂档时,⽂档已更改。原始读取不可重复。如果只有在作者全部完成编写后编辑⼈员才可以读取⽂档,则可以避免该问题。
4.幻觉读是指当事务不是独⽴执⾏时发⽣的⼀种现象,例如第⼀个事务对⼀个表中的数据进⾏了修改,这种修改涉及到表中的全部数据⾏。同时,第⼆个事务也修改这个表中的数据,这种修改是向表中插⼊⼀⾏新数据。那么,以后就会发⽣操作第⼀个事务的⽤户发现表中还有没有修改的数据⾏,就好象发⽣了幻觉⼀样。例如,⼀个编辑⼈员更改作者提交的⽂档,但当⽣产部门将其更改内容合并到该⽂档的主复本时,发现作者已将未编辑的新材料添加到该⽂档中。如果在编辑⼈员和⽣产部门完成对原始⽂档的处理之前,任何⼈都不能将新材料添加到⽂档中,则可以避免该问题。
所以,处理多⽤户并发访问的⽅法是加锁。锁是防⽌其他事务访问指定的资源控制、实现并发控制的⼀种主要⼿段。当⼀个⽤户锁住数据库中的某个对象时,其他⽤户就不能再访问该对象。加锁对并发访问的影响体现在锁的粒度上。为了控制锁定的资源,应该⾸先了解系统的空间管理。在SQL Server 2000系统中,最⼩的空间管理单位是页,⼀个页有8K。所有的数据、⽇志、索引都存放在页上。另外,使⽤页有⼀个限制,这就是表中的⼀⾏数据必须在同⼀个页上,不能跨页。页上⾯的空间管理单位是盘区,⼀个盘区是8个连续的页。表和索引的最⼩占⽤单位是盘区。数据库是由⼀个或者多个表或者索引组成,即是由多个
盘区组成。放在⼀个表上的锁限制对整个表的并发访问;放在盘区上的锁限制了对整个盘区的访问;放在数据页上的锁限制了对整个数据页的访问;放在⾏上的锁只限制对该⾏的并发访问。
SQL Server 2000 具有多粒度锁定,允许⼀个事务锁定不同类型的的资源。为了使锁定的成本减⾄最少,SQL Server ⾃动将资源锁定在适合任务的级别。锁定在较⼩的粒度(例如⾏)可以增加并发但需要较⼤的开销,因为如果锁定了许多⾏,则需要控制更多的锁。锁定在较⼤的粒度(例如表)就并发⽽⾔是相当昂贵的,因为锁定整个表限制了其它事务对表中任意部分进⾏访问,但要求的开销较低,因为需要维护的锁较少。SQL Server 可以锁定⾏、页、扩展盘区、表、库等资源。
⾏是可以锁定的最⼩空间, ⾏级锁占⽤的数据资源最少,所以在事务的处理过程中,允许其他事务继续操纵同⼀个表或者同⼀个页的其他数据,⼤⼤降低了其他事务等待处理的时间,提⾼了系统的并发性。
页级锁是指在事务的操纵过程中,⽆论事务处理数据的多少,每⼀次都锁定⼀页,在这个页上的数据不能被其他事务操纵。在SQL
Server 7.0以前,使⽤的是页级锁。页级锁锁定的资源⽐⾏级锁锁定的数据资源多。在页级锁中,即使是⼀个事务只操纵页上的⼀⾏数据,那么该页上的其他数据⾏也不能被其他事务使⽤。因此,当使⽤页级锁时,会出现数据的浪费现象,也就是说,在同⼀个页上会出现数据被占⽤却没有使⽤的现象。
在这种现象中,数据的浪费最多不超过⼀个页上的数据⾏。
表级锁也是⼀个⾮常重要的锁。表级锁是指事务在操纵某⼀个表的数据时,锁定了这个数据所在的整个表,其他事务不能访问该表中的其他数据。当事务处理的数据量⽐较⼤时,⼀般使⽤表级锁。表级锁的特点是使⽤⽐较少的系统资源,但是却占⽤⽐较多的数据资源。与⾏级锁和页级锁相⽐,表级锁占⽤的系统资源例如内存⽐较少,但是占⽤的数据资源却是最⼤。在表级锁时,有可能出现数据的⼤量浪费现象,因为表级锁锁定整个表,那么其他的事务都不能操纵表中的其他数据。
盘区锁是⼀种特殊类型的锁,只能⽤在⼀些特殊的情况下。簇级锁就是指事务占⽤⼀个盘区,这个盘区不能同时被其他事务占⽤。例如在创建数据库和创建表时,系统分配物理空间时使⽤这种类型的锁。系统是按照盘区分配空间的。当系统分配空间时,使⽤盘区锁,防⽌其他事务同时使⽤同⼀个盘区。当系统完成分配空间之后,就不再使⽤这种类型的盘区锁。特别是,当涉及到对数据操作的事务时,不使⽤盘区锁。
数据库级锁是指锁定整个数据库,防⽌任何⽤户或者事务对锁定的数据库进⾏访问。数据库级锁是⼀种⾮常特殊的锁,它只是⽤于数据库的恢复操作过程中。这种等级的锁是⼀种最⾼等级的锁,因为它控制整个数据库的操作。只要对数据库进⾏恢复操作,那么就需要设置数据库为单⽤户模式,这样系统就能防⽌其他⽤户对该数据库进⾏各种操作。
⾏级锁是⼀种最优锁,因为⾏级锁不可能出现数据既被占⽤⼜没有使⽤的浪费现象。但是,如果⽤户事务中频繁对某个表中的多条记录操作,将导致对该表的许多记录⾏都加上了⾏级锁,数据库系统中锁的数⽬会急剧增加,这样就加重了系统负荷,影响系统性能。因此,在SQL Server中,还⽀持锁升级(lock escalation)。所谓锁升级是指调整锁的粒度,将多个低粒度的锁替换成少数的更⾼粒度的锁,以此来降低系统负荷。在SQL Server中当⼀个事务中的锁较多,达到锁升级门限时,系统⾃动将⾏级锁和页⾯锁升级为表级锁。特别值得注意的是,在SQL Server中,锁的升级门限以及锁升级是由系统⾃动来确定的,不需要⽤户设置。
在SQL Server数据库中加锁时,除了可以对不同的资源加锁,还可以使⽤不同程度的加锁⽅式,即锁有多种模式,SQL Server中锁模式包括:
1.共享锁 SQL Server中,共享锁⽤于所有的只读数据操作。共享锁是⾮独占的,允许多个并发事务读取其锁定的资源。默认情况下,数据被读取后,SQL Server⽴即释放共享锁。例如,执⾏查询“SELECT * FROM AUTHORS”时,⾸先锁定第⼀页,读取之后,释放对第⼀页的锁定,然后锁定第⼆页。这样,就允许在读操作过程中,修改未被锁定的第⼀页。但是,事务隔离级别连接选项设置和SELECT语句中的锁定设置都可以改变SQL Server的这种默认设置。例如,“ SELECT * FROM AUTHORS HOLDLOCK”就要求在整个查询过程中,保持对表的锁定,直到查询完成才释放锁定。
2.更新锁 更新锁在修改操作的初始化阶段⽤来锁定可能要被修改的资源,这样可以避免使⽤共享锁造成的死锁现象。因为使⽤共享锁时,修改数据的操作分为两步,⾸先获得⼀个共享锁,读取数据,然后将共享锁升级为排它锁,然后再执⾏修改操作。这样如果同时有两个或多个事务同时对⼀个事务申请了共享锁,在修改数据的时候,这些事务都要将共享锁升级为排它锁。这时,这些事务都不会释放共享锁⽽是⼀直等待对⽅释放,这样就造成了死锁。如果⼀个数据在修改前直接申请更新锁,在数据修改的时候再升级为排它锁,就可以避免死锁。
3.排它锁 排它锁是为修改数据⽽保留的。它所锁定的资源,其他事务不能读取也不能修改。
4.结构锁 执⾏表的数据定义语⾔ (DDL) 操作(例如添加列或除去表)时使⽤架构修改 (Sch-M) 锁。当编译查询时,使⽤架构稳定性 (Sch-S) 锁。架构稳定性 (Sch-S) 锁不阻塞任何事务锁,包括排它锁。因此在编译查询时,其它事务(包括在表上有排它锁的事务)都能继续运⾏。但不能在表上执⾏ DDL 操作。
5.意向锁 意向锁说明SQL Server有在资源的低层获得共享锁或排它锁的意向。例如,表级的共享意向锁说明事务意图将排它锁释放到表中的页或者⾏。意向锁⼜可以分为共享意向锁、独占意向锁和共享式独占意向锁。共享意向锁说明事务意图在共享意向锁所锁定的低层资源上放置共享锁来读取数据。独占意向锁说明事务意图在共享意向锁所锁定的低层资源上放置排它锁来修改数据。共享式排它锁说明事务允许其他事务使⽤共享锁来读取顶层资源,并意图在该资源低层上放置排它锁。
6.⼤容量更新锁 当将数据⼤容量复制到表,且指定了 TABLOCK 提⽰或者使⽤ sp_tableoption 设置了 table lock on bulk 表选项时,将使⽤⼤容量更新 锁。⼤容量更新锁允许进程将数据并发地⼤容量复制到同⼀表,同时防⽌其它不进⾏⼤容量复制数据的进程访问该表。
SQL Server系统中建议让系统⾃动管理锁,该系统会分析⽤户的SQL语句要求,⾃动为该请求加上合适的锁,⽽且在锁的数⽬太多时,系统会⾃动进⾏锁升级。如前所述,升级的门限由系统⾃动配置,并不需要⽤户配置。 在实际应⽤中,有时为了应⽤程序正确运⾏和保持数据的⼀致性,必须⼈为地给数据库的某个表加锁。⽐如,在某应⽤程序的⼀个事务操作中,需要根据⼀编号对⼏个数据表做统计操作,为保证统计数据时间的⼀致性和正确性,从统计第⼀个表开始到全部表结束,其他应⽤程序或事务不能再对这⼏个表写⼊数据,这个时候,该应⽤程序希望在从统计第⼀个数据表开始或在整个事务开始时能够由程序⼈为地(显式地)锁定这⼏个表,这就需要⽤到⼿⼯加锁(也称显式加锁)技术。
可以使⽤ SELECT、INSERT、UPDATE 和 DELETE 语句指定表级锁定提⽰的范围,以引导 Microsoft SQL Server
2000 使⽤所需的锁类型。当需要对对象所获得锁类型进⾏更精细控制时,使⽤表级锁定提⽰更改默认的锁定⾏为。
所指定的表级锁定提⽰有如下⼏种:
1. HOLDLOCK: 在该表上保持共享锁,直到整个事务结束,⽽不是在语句执⾏完⽴即释放所添加的锁。
2. NOLOCK:不添加共享锁和排它锁,当这个选项⽣效后,可能读到未提交读的数据或“脏数据”,这个选项仅仅应⽤于SELECT语句。
3. PAGLOCK:指定添加页锁(否则通常可能添加表锁)。
4. READCOMMITTED⽤与运⾏在提交读隔离级别的事务相同的锁语义执⾏扫描。默认情况下,SQL Server 2000 在此隔离级别上操作。。
5. READPAST: 跳过已经加锁的数据⾏,这个选项将使事务读取数据时跳过那些已经被其他事务锁定的数据⾏,⽽不是阻塞直到其他事务释放锁,READPAST仅仅应⽤于READ COMMITTED隔离性级别下事务操作中的SELECT语句操作。
6. READUNCOMMITTED:等同于NOLOCK。
7. REPEATABLEREAD:设置事务为可重复读隔离性级别。
8. ROWLOCK:使⽤⾏级锁,⽽不使⽤粒度更粗的页级锁和表级锁。
9. SERIALIZABLE:⽤与运⾏在可串⾏读隔离级别的事务相同的锁语义执⾏扫描。等同于 HOLDLOCK。
10. TABLOCK:指定使⽤表级锁,⽽不是使⽤⾏级或页⾯级的锁,SQL Server在该语句执⾏完后释放这个锁,⽽如果同时指定了HOLDLOCK,该锁⼀直保持到这个事务结束。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论