SQL Sever数据库中的锁25例

VS与SQL Sever(C语言操作数据库) 作者这里使用的是程序是:SQL Sever。 阅读详情

SQL Sever数据库中的锁25例

数据库锁Table of Contents

 

1 前言

数据库大并发操作要考虑死锁和锁的性能问题。看到网上大多语焉不详(尤其更新锁),所以这里做个简明解释,为下面描述方便,这里用T1代表一个数据库执行请求,T2代表另一个请求,也可以理解为T1为一个线程,T2 为另一个线程。T3,T4以此类推。下面以SQL Server(2005)为例。

2 锁的种类
  1. 共享锁(Shared lock)。 例1:----------------------------------------T1: select * from table (请想象它需要执行1个小时之久,后面的sql语句请都这么想象)T2: update table set column1='hello'过程:T1运行 (加共享锁)T2运行If T1 还没执行完 T2等......else 锁被释放 T2执行endifT2之所以要等,是因为T2在执行update前,试图对table表加一个排他锁,而数据库规定同一资源上不能同时共存共享锁和排他锁。所以T2必须等T1执行完,释放了共享锁,才能加上排他锁,然后才能开始执行update语句。例2:----------------------------------------T1: select * from tableT2: select * from table这里T2不用等待T1执行完,而是可以马上执行。分析:T1运行,则table被加锁,比如叫lockAT2运行,再对table加一个共享锁,比如叫lockB。两个锁是可以同时存在于同一资源上的(比如同一个表上)。这被称为共享锁与共享锁兼容。这意味着共享锁不阻止其它session同时读资源,但阻止其它session update例3:----------------------------------------T1: select * from tableT2: select * from tableT3: update table set column1='hello'这次,T2不用等T1运行完就能运行,T3却要等T1和T2都运行完才能运行。因为T3必须等T1和T2的共享锁全部释放才能进行加排他锁然后执行update操作。例4:(死锁的发生)----------------------------------------T1:begin transelect * from table (holdlock) (holdlock意思是加共享锁,直到事物结束才释放)update table set column1='hello'T2:begin transelect * from table(holdlock)update table set column1='world'假设T1和T2同时达到select,T1对table加共享锁,T2也对加共享锁,当T1的select执行完,准备执行update时,根据锁机制,T1的共享锁需要升级到排他锁才能执行接下来的update.在升级排他锁前,必须等table上的其它共享锁释放,但因为holdlock这样的共享锁只有等事务结束后才释放,所以因为T2的共享锁不释放而导致T1等(等T2释放共享锁,自己好升级成排他锁),同理,也因为T1的共享锁不释放而导致T2等。死锁产生了。例5:----------------------------------------T1:begin tranupdate table set column1='hello' where id=10T2:begin tranupdate table set column1='world' where id=20这种语句虽然最为常见,很多人觉得它有机会产生死锁,但实际上要看情况,如果id是主键上面有索引,那么T1会一下子找到该条记录(id=10的记录),然后对该条记录加排他锁,T2,同样,一下子通过索引定位到记录,然后对id=20的记录加排他锁,这样T1和T2各更新各的,互不影响。T2也不需要等。但如果id是普通的一列,没有索引。那么当T1对id=10这一行加排他锁后,T2为了找到id=20,需要对全表扫描,那么就会预先对表加上共享锁或更新锁或排他锁(依赖于数据库执行策略和方式,比如第一次执行和第二次执行数据库执行策略就会不同)。但因为T1已经为一条记录加了排他锁,导致T2的全表扫描进行不下去,就导致T2等待。死锁怎么解决呢?一种办法是,如下:例6:----------------------------------------T1:begin transelect * from table(xlock) (xlock意思是直接对表加排他锁)update table set column1='hello'T2:begin transelect * from table(xlock)update table set column1='world'这样,当T1的select 执行时,直接对表加上了排他锁,T2在执行select时,就需要等T1事物完全执行完才能执行。排除了死锁发生。但当第三个user过来想执行一个查询语句时,也因为排他锁的存在而不得不等待,第四个、第五个user也会因此而等待。在大并发情况下,让大家等待显得性能就太友好了,所以,这里引入了更新锁。
  2. 更新锁(Update lock) 为解决死锁,引入更新锁。例7:----------------------------------------T1:begin transelect * from table(updlock) (加更新锁)update table set column1='hello'T2:begin transelect * from table(updlock)update table set column1='world'更新锁的意思是:“我现在只想读,你们别人也可以读,但我将来可能会做更新操作,我已经获取了从共享锁(用来读)到排他锁(用来更新)的资格”。一个事物只能有一个更新锁获此资格。T1执行select,加更新锁。T2运行,准备加更新锁,但发现已经有一个更新锁在那儿了,只好等。当后来有user3、user4...需要查询table表中的数据时,并不会因为T1的select在执行就被阻塞,照样能查询,相比起例6,这提高了效率。例8:----------------------------------------T1: select * from table(updlock) (加更新锁)T2: select * from table(updlock) (等待,直到T1释放更新锁,因为同一时间不能在同一资源上有两个更新锁)T3: select * from table (加共享锁,但不用等updlock释放,就可以读)这个例子是说明:共享锁和更新锁可以同时在同一个资源上。这被称为共享锁和更新锁是兼容的。例9:----------------------------------------T1:beginselect * from table(updlock) (加更新锁)update table set column1='hello' (重点:这里T1做update时,不需要等T2释放什么,而是直接把更新锁升级为排他锁,然后执行update)T2:beginselect * from table (T1加的更新锁不影响T2读取)update table set column1='world' (T2的update需要等T1的update做完才能执行)我们以这个例子来加深更新锁的理解,第一种情况:T1先达,T2紧接到达;在这种情况中,T1先对表加更新锁,T2对表加共享锁,假设T2的select先执行完,准备执行update,发现已有更新锁存在,T2等。T1执行这时才执行完select,准备执行update,更新锁升级为排他锁,然后执行update,执行完成,事务结束,释放锁,T2才轮到执行update。第二种情况:T2先达,T1紧接达;在这种情况,T2先对表加共享锁,T1达后,T1对表加更新锁,假设T2 select先结束,准备update,发现已有更新锁,则等待,后面步骤就跟第一种情况一样了。这个例子是说明:排他锁与更新锁是不兼容的,它们不能同时加在同一子资源上。
  3. 排他锁(独占锁,Exclusive Locks) 这个简单,即其它事务既不能读,又不能改排他锁锁定的资源。例10T1: update table set column1='hello' where id<1000T2: update table set column1='world' where id>1000假设T1先达,T2随后至,这个过程中T1会对id<1000的记录施加排他锁.但不会阻塞T2的update。例11 (假设id都是自增长且连续的)T1: update table set column1='hello' where id<1000T2: update table set column1='world' where id>900如同例10,T1先达,T2立刻也到,T1加的排他锁会阻塞T2的update.
  4. 意向锁(Intent Locks) 意向锁就是说在屋(比如代表一个表)门口设置一个标识,说明屋子里有人(比如代表某些记录)被锁住了。另一个人想知道屋子里是否有人被锁,不用进屋子里一个一个的去查,直接看门口标识就行了。当一个表中的某一行被加上排他锁后,该表就不能再被加表锁。数据库程序如何知道该表不能被加表锁?一种方式是逐条的判断该表的每一条记录是否已经有排他锁,另一种方式是直接在表这一层级检查表本身是否有意向锁,不需要逐条判断。显然后者效率高。例12:----------------------------------------T1: begin tran select * from table (xlock) where id=10 --意思是对id=10这一行强加排他锁T2: begin tran select * from table (tablock) --意思是要加表级锁 假设T1先执行,T2后执行,T2执行时,欲加表锁,为判断是否可以加表锁,数据库系统要逐条判断table表每行记录是否已有排他锁,如果发现其中一行已经有排他锁了,就不允许再加表锁了。只是这样逐条判断效率太低了。实际上,数据库系统不是这样工作的。当T1的select执行时,系统对表table的id=10的这一行加了排他锁,还同时悄悄的对整个表加了意向排他锁(IX),当T2执行表锁时,只需要看到这个表已经有意向排他锁存在,就直接等待,而不需要逐条检查资源了。例13:----------------------------------------T1: begin tran update table set column1='hello' where id=1T2: begin tran update table set column1='world' where id=1这个例子和上面的例子实际效果相同,T1执行,系统对table同时对行家排他锁、对页加意向排他锁、对表加意向排他锁。
  5. 计划锁(Schema Locks) 例14:----------------------------------------alter table .... (加schema locks,称之为Schema modification (Sch-M) locksDDL语句都会加Sch-M锁该锁不允许任何其它session连接该表。连都连不了这个表了,当然更不用说想对该表执行什么sql语句了。例15:----------------------------------------用jdbc向数据库发送了一条新的sql语句,数据库要先对之进行编译,在编译期间,也会加锁,称之为:Schema stability (Sch-S) locksselect * from tableA编译这条语句过程中,其它session可以对表tableA做任何操作(update,delete,加排他锁等等),但不能做DDL(比如alter table)操作。
  6. Bulk Update Locks 主要在批量导数据时用(比如用类似于oracle中的imp/exp的bcp命令)。不难理解,程序员往往也不需要关心,不赘述了。
3 何时加锁?如何加锁,何时加锁,加什么锁,你可以通过hint手工强行指定,但大多是数据库系统自动决定的。这就是为什么我们可以不懂锁也可以高高兴兴的写SQL。例15:----------------------------------------T1: begin tran update table set column1='hello' where id=1T2: SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED -- 事物隔离级别为允许脏读 go select * from table where id=1这里,T2的select可以查出结果。如果事物隔离级别不设为脏读,则T2会等T1事物执行完才能读出结果。数据库如何自动加锁的?1) T1执行,数据库自动加排他锁2) T2执行,数据库发现事物隔离级别允许脏读,便不加共享锁。不加共享锁,则不会与已有的排他锁冲突,所以可以脏读。例16:----------------------------------------T1: begin tran update table set column1='hello' where id=1T2: select * from table where id=1 --为指定隔离级别,则使用系统默认隔离级别,它不允许脏读如果事物级别不设为脏读,则:1) T1执行,数据库自动加排他锁2) T2执行,数据库发现事物隔离级别不允许脏读,便准备为此次select过程加共享锁,但发现加不上,因为已经有排他锁了,所以就 等啊等。直到T1执行完,释放了排他锁,T2才加上了共享锁,然后开始读....4 锁的粒度

锁的粒度就是指锁的生效范围,就是说是行锁,还是页锁,还是整表锁. 锁的粒度同样既可以由数据库自动管理,也可以通过手工指定hint来管理。

例17:----------------------------------------T1: select * from table (paglock)T2: update table set column1='hello' where id>10T1执行时,会先对第一页加锁,读完第一页后,释放锁,再对第二页加锁,依此类推。假设前10行记录恰好是一页(当然,一般不可能一页只有10行记录),那么T1执行到第一页查询时,并不会阻塞T2的更新。例18:----------------------------------------T1: select * from table (rowlock)T2: update table set column1='hello' where id=10T1执行时,对每行加共享锁,读取,然后释放,再对下一行加锁;T2执行时,会对id=10的那一行试图加锁,只要该行没有被T1加上行锁,T2就可以顺利执行update操作。例19:----------------------------------------T1: select * from table (tablock)T2: update table set column1='hello' where id = 10T1执行,对整个表加共享锁. T1必须完全查询完,T2才可以允许加锁,并开始更新。以上3例是手工指定锁的粒度,也可以通过设定事物隔离级别,让数据库自动设置锁的粒度。不同的事物隔离级别,数据库会有不同的加锁策略(比如加什么类型的锁,加什么粒度的锁)。具体请查联机手册。5 锁与事物隔离级别的优先级手工指定的锁优先,例20:----------------------------------------T1: GO SET TRANSACTION ISOLATION LEVEL SERIALIZABLE GO BEGIN TRANSACTION SELECT * FROM table (NOLOCK) GOT2: update table set column1='hello' where id=10T1是事物隔离级别为最高级,串行锁,数据库系统本应对后面的select语句自动加表级锁,但因为手工指定了NOLOCK,所以该select语句不会加任何锁,所以T2也就不会有任何阻塞。6 数据库的其它重要Hint以及它们的区别1) holdlock 对表加共享锁,且事物不完成,共享锁不释放。2) tablock 对表加共享锁,只要statement不完成,共享锁不释放。 与holdlock区别,见下例: 例21 ---------------------------------------- T1: begin tran select * from table (tablock) T2: begin tran update table set column1='hello' where id = 10 T1执行完select,就会释放共享锁,然后T2就可以执行update. 此之谓tablock. 下面我们看holdlock 例22 ---------------------------------------- T1: begin tran select * from table (holdlock) T2: begin tran update table set column1='hello' where id = 10 T1执行完select,共享锁仍然不会释放,仍然会被hold(持有),T2也因此必须等待而不能update. 当T1最后执行了commit或 rollback说明这一个事物结束了,T2才取得执行权。 3) TABLOCKX 对表加排他锁 例23: ---------------------------------------- T1: select * from table(tablockx) (强行加排他锁) 其它session就无法对这个表进行读和更新了,除非T1执行完了,就会自动释放排他锁。 例24: ---------------------------------------- T1: begin tran select * from table(tablockx) 这次,单单select执行完还不行,必须整个事物完成(执行了commit或rollback后)才会释放排他锁。 4) xlock 加排他锁 那它跟tablockx有何区别呢? 它可以这样用, 例25: ---------------------------------------- select * from table(xlock paglock) 对page加排他锁 而TABLELOCX不能这么用。 xlock还可这么用:select * from table(xlock tablock) 效果等同于select * from table(tablockx)7 锁的超时等待

例26

SET LOCK_TIMEOUT 4000 用来设置锁等待时间,单位是毫秒,4000意味着等待4秒可以用select @@LOCK_TIMEOUT查看当前session的锁超时设置。-1 意味着永远等待。T1: begin tran udpate table set column1='hello' where id = 10T2: set lock_timeout 4000 select * from table wehre id = 10

T2执行时,会等待T1释放排他锁,等了4秒钟,如果T1还没有释放排他锁,T2就会抛出异常: Lock request time out period exceeded.

8 附:各种锁的兼容关系表| Requested mode | IS | S | U | IX | SIX | X || Intent shared (IS) | Yes | Yes | Yes | Yes | Yes | No || Shared (S) | Yes | Yes | Yes | No | No | No || Update (U) | Yes | Yes | No | No | No | No || Intent exclusive (IX) | Yes | No | No | Yes | No | No || Shared with intent exclusive (SIX) | Yes | No | No | No | No | No || Exclusive (X) | No | No | No | No | No | No |9 如何提高并发效率
  1. 悲观锁:利用数据库本身的锁机制实现。通过上面对数据库锁的了解,可以根据具体业务情况综合使用事务隔离级别与合理的手工指定锁的方式比如降低锁的粒度等减少并发等待。
  2. 乐观锁:利用程序处理并发。原理都比较好理解,基本一看即懂。方式大概有以下3种
    1. 对记录加版本号.
    2. 对记录加时间戳.
    3. 对将要更新的数据进行提前读取、事后对比。

不论是数据库系统本身的锁机制,还是乐观锁这种业务数据级别上的锁机制,本质上都是对状态位的读、写、判断。

10 后记

我不是DBA,数据库学的不好。如果有什么错误之处,请指出,在此表示感谢。


SQL sever2012:(一)创建数据库和表 硬件:计算机。 软件:SQL sever2012数据库软件 阅读详情

相关推荐

SQL Sever数据库中的锁

1 前言        数据库大并发操作要考虑死锁和锁的性能问题。看到网上大多语焉不详(尤其更新锁),所以这里做个简明解释,为下面描述方便,这里用T1代表一个数据库执行请求,T2代表另一个请求,也可以理解为T1为一个线程,T2 为另一个线程。T3,T4以此类推。下面以SQL Server(2005)为例。        2 锁的种类 共享锁(Shared lock)。 例1:--

易戎伊的专栏 581

一例胜千言,SQL Sever数据库中的锁25例

数据库锁 Table of Contents 1 前言 2 锁的种类 3 何时加锁? 4 锁的粒度 5 锁与事物隔离级别的优先级 6 数据库的其它重要Hint以及它们的区别 7 锁的超时等待 8 附:各种锁的兼容关系表 9 如何提高并发效率 10 后记 1 前言 数据库大并发操作要考虑死锁和锁的性能问题。看到网上大多语焉不详(尤其更新锁),所以这里做个简明解释

tianlianchao1982的专栏 735

SQL sever2008数据库备份、还原以及库检查

SQL sever2008数据库备份、还原以及库检查

m0_71406734的博客 2591

SQL Sever 数据仓库的解决方案

1 引言数据仓库的概念一经出现,就首先被用于金融、电信、保险等主要的传统数据处理密集型行业。数据仓库将分布在企业网络中不同信息岛上的业务数据集成到一起,存储在一个单一的集成关系型数据库中,利用这种集成信息,可方便用户对信息的访问,更可使决策人员对一段时间内的历史数据进行分析,研究事务发展走势。 2 数据仓库技术2.1 传统数据库与数据仓库技术分析    信息处理的类型主要分事务

漫漫长路 6896

Unity3D连接SQL Sever数据库

在编写网络游戏时,我们经常需要让玩家注册账号,这时我们就需要用数据库来保存玩家数据,本文简单介绍一下Unity3D如何连接SQL Sever数据库。(本人用的是SQL Sever2012)。 1.找到System.Data.dll文件,默认的地址是在C:\Program Files\Unity\Editor\Data\Mono\lib\mono\unity,这个根据你所安装的路径有关。 2.将

luoshaochuan1993的专栏 2270

课堂点名器V4(写入SQL Sever数据库)

任务描述: 用Python实现一个简单课堂点名器V4 要求: (1). 以18级网工学生名单为例,从外部文件导入学生信息,并将学生信息存入MySQL数据库,随机对班级所有同学进行点名; (2). 判断未到学生是否有请假条,有则视为请假,无则视为旷课。 (3). 对点名结束后进入教室的学生将旷课改为迟到。 (4). 对中途离开课堂学生计为早退(需要考虑学生既是迟到又是早退的情况)。 (5). 将未...

weixin_44740101的博客 416

SQL sever创建数据库数据表

创建数据库和数据表 一、目的: 掌握在SQL Server中使用对象资源管理器和SQL命令创建数据库与修改数据库的方法。 掌握在SQL Server中使用对象资源管理器或者SQL命令创建数据表和修改数据表的方法(以SQL命令为重点)。 二、环境概述: SQL Server 2019 SQL Server Management Studio 管理工具 三、数据库的创建 使用对象资源管理器创建数据库,给出关键步骤的截图和说明。 ①打开管理工具,连接数据库引擎。 ② 在对象资源管理器中右击数据库,

weixin_45946210的博客 1万+

手把手教你用EGM96模型校正DEM数据(含在线工具推荐)

本文详细介绍了如何使用EGM96地球重力场模型校正DEM数据中的高程偏差。通过对比WGS84椭球面与大地水准面的差异,解释了校正原理,并提供了从在线工具快速验证到Python脚本批量处理的全流程实战指南,帮助GIS开发者和数据分析师确保高程数据基准一致,提升空间分析精度。

ttt77的博客 1007

C# 连接SQL Sever 数据库

上面这种输入用户名和密码的是使用了 SQL Server 身份验证,如果要使用 windows 身份验证,只需要将 “User Id = Csharp;方法一的 scsb 由于不是string类型,所以需要使用ToString()方法。ExecuteScalar() : 作用是获取返回表上的第一个单元格的数据。获取服务器名,用户名,密码以及你要访问的数据库。方法二的 ConStr 可以直接作为参数传进去。根据上面两种方法不同创建连接的方法也不同。打开数据库的时候注意需要捕捉异常。

qq_44544908的博客 6106

用Frida-RPC搞定大麦App最新版签名:一个脚本解决x-sign和x-mini-wua

本文深入解析大麦App最新版签名机制(x-sign和x-mini-wua),详细介绍如何利用Frida-RPC技术开发稳定脚本获取签名参数。通过实战案例展示Java上下文切换、参数序列化等关键技术解决方案,为安全研究和技术验证提供可靠方案。

weixin_42525738的博客 643

如何有效使用Project(1)——编制进度计划、保存基准

1.前言: 软件产品的研发、升级、定制等,一般都是以项目的形式进行,此时项目进度计划以及资源使用情况就变成了项目经理关注的重点。如何让项目计划有效可控,及时暴露问题?如何查看资源的负荷情况,看资源分配是否合理。 当然,如果你的公司已经实施了专门的PM软件来监督管控,可以忽略本文。否则,你可以用微软的Project来做到这一工作。 我也算是一个专业的从事PM软件产品的人(虽然我们的客户都是制造...

weixin_34236869的博客 2115

SQL SEVER2012链接Oracle数据库方法

SQL SEVER2012链接Oracle数据库方法

qq_38903177的博客 5499

UR5双臂Gazebo仿真(Python)

近来在Gazebo上搭了一个ur5双臂仿真平台。 差不多就是以下这样。 使用rostopic list查看一下话题,如下 显然,采用/left_arm_controller/follow_joint_trajectory/goal和/right_arm_controller/follow_joint_trajectory/goal两个话题来控制双臂的运动。 现在的问题是,如何保证双臂运动的一致性,即如何能保证双臂能同时接受到以上两个消息。 思路一:设置/left_arm_controlle

qq_42823342的博客 2233

SQL sever中的视图

SQL sever中的视图

m0_71406734的博客 8074

LLMOps的崛起:如何利用Langfuse和Opik构建高效的模型监控与评估体系

本文探讨了LLMOps的崛起,详细介绍了如何利用Langfuse和Opik构建高效的模型监控与评估体系。通过开源工具Langfuse的全景监控方案和Opik的三层评估体系,帮助AI工程团队实现大语言模型的全生命周期管理,提升模型性能和迭代效率。文章还提供了实战技巧和工具链集成方案,助力企业优化AI应用。

ll5678的博客 680

玩转 InternVL3.5 轻量级实战:从部署到优化的全记录

玩转 InternVL3.5 轻量级实战:从部署到优化的全记录

jacke121的专栏 626

SQL sever中的约束

SQL sever中的约束

m0_71406734的博客 5931

8.26华为OD机试真题 新系统【仓库查询】

华为OD机试真题 新系统【仓库查询】,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解,以及在线OJ模拟做题。华为OD机试真题 【仓库查询】多语言题解。

qq_45776114的博客 548

认识SQL sever

认识SQL sever

m0_71406734的博客 3011

华为OD机试 - 战士技能规划设计 - 数组(Python/JS/C/C++ 新系统 100分)

本专栏收录于《华为OD机试真题(Python/JS/C/C++)》。刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新。你为一款动作游戏设计战士角色的技能:战士每个技能会消耗不同能量,释放技能有 2 个约束:连续释放技能数量不能超过 m 个,技能能量总和不能超过能量上限 k;如果超过则必须中断当前技能,进入调息状态(即分段)。战士有一项爆发技巧:在单次战斗中有一次

学Java,找哪吒 233

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

Qt 连接并使用 SQL Sever数据库

可以选上默认数据库是哪一个需要用的数据库】

3112

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

c语言中如何连接SQL SEVER 2000数据库

c语言中如何连接SQL SEVER 2000数据库   #define DBNTWIN32       //   must   identify   operating   system   environment     #include   "windows.h"     #include        #include          //   DB-LIB   heade

厚德载物 1559

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

一例胜千言,详谈SQL Sever数据库锁

数据库锁 Table of Contents 1 前言 2 锁的种类 3 何时加锁? 4 锁的粒度 5 锁与事物隔离级别的优先级 6 数据库的其它重要Hint以及它们的区别 7 锁的超时等待 8 附:各种锁的兼容关系表 9 如何提高并发效率 10 后记 1 前言 数据库大并发操作要考虑死锁和锁的性能问题。看到网上大多语焉...

mmonkeyer的博客 1652

SQL sever中的索引

SQL sever中的索引

m0_71406734的博客 6802
上一篇: java 并发
下一篇: java中StringBuffer和StringBuilder的区别
lb8607
博客等级 码龄18年 17粉丝 18原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值