当前位置:文档之家› sqlserver2005事务与锁定

sqlserver2005事务与锁定

sqlserver2005事务与锁定
sqlserver2005事务与锁定

终于定下心来写这个事务与锁定的文章,下笔后才发现真的很难写,交易中事务与锁定这个话题过于复杂,甚至有些还摸不着(就是通过DMV或DMF或其它工具你可能很难看到它的踪影),让人有点让人望而止步,但是既然说了要写,似乎不继续下去不是我的风格。在接下来的几篇文章(其实我也不知道要几篇)里我就事务与锁定这个话题写写,由SQL2005的并发模型引入事务,在事务的概念里展开锁定,本着先概念后实例的原则,和大家一起来学习,有不当之处希望大家指正。

一、并发及并发控制模型

对于这个我在<< SQL2005数据库引擎结构>>一文有所提及,你可以通过如下链接进行访问:SQL2005数据库引擎结构(三)并有一起的意思,显然就是多个的意思啦,光书面来理解并发就是多个东西同时发生,在数据库并发就是多个进程同时取、存数据库里数据的能力。着眼我们开发的系统,当然是激动态的并互不打架的并发用户进程越多并发能力就越强大啦,你想想看好多的网上购物系统,如果没有并发处理的能力,那么在上面登记的用户信息、商品有库存信息及用户帐户信息很难保证正确性和一致性,比如一个物品本身库存只有100个,结果如果100人同时在线进行预定,库存就有可能搞一个100-1的效果出来。

很显然对上述的例子我们希望一个进程在修改库存数据时必须阻止其它进程读或修改数据,或是正在读的用户进程限制其它活动的用户进程进行读或修改的操作,这样一来势必造成系统的并发性能下降,但是如果不采用这种办法又无法保证数据正确性和一致性。那怎么解决这个问题呢,办法只有通过不同的并发模式来管理这些并发事件。我们下面来理解并发控制的模式、并发下可能发生的非一致数据行为,即并发副作用,并由模式及数据行为引入事务及相关的5个隔离等级等概念,进而来理解不同隔离等级下并发实现的机理,显然我们自己也就可以回答上面这个问题了。

并发控制模式:一般并发控制模式有两种:积极并发(又称乐观并发)和消极并发(又称悲观并发)。积极并发是SQL2005才引入的新模式,在2005以前的版本其实只有唯一的并发模式即:消极并发。那什么是消极并发呢?消极并发就是SQLSERVER默认行为是进程以获取锁的方式来阻止其它进程对正在使用的数据进行修改的能力。对于数据库来说对数据修改的操作进程肯定很多,这些进程肯定都会去影响其它进程读取数据的能力,反之,对数据进行读时加上锁也一定会影响其它进程修改数据的能力,简而言之,就是读取与修改数据之间是冲突的、互相阻塞的。乐观并发是SQL2005利用一个行版本控制器的新技术来处理上述的冲突。行版本控制器在当前进程读取数据时生成旧版本的数据,使得其它请求读的进程能看到当前进程一开始读取时的数据状态,并且不受当前进程或其它进程对数据进行修改的影响。简而言之读与修改之间是不冲突的,但是修改与修改之间还是冲突的。

对于这两种并发模式两个进程同时请求数据修改必然会冲突的,除此以外的差别在于一个是在冲突发生前进行控制,另一个在冲突发生了进行协调处理。这好比生活一样,两种方式就是两种不同的人生,一种消极怠工一种积极向上。

二、并发下可能发生的并发副作用:丢失更新、脏读、不可重复读、幻影。

为了把这些可能发生的并发副作用说清楚,我们先―布置‖一个场景:这是一个卖工艺石头的小商店,平时在前场完成交易,客户凭单据到后场领取石头,AMM 和BMM是营业员,她们平时掌握库存数是通过大厅里的一块LED显示牌得之,并且在各自完成一笔交易后修改LED显示,以保证数据的实时性。在这个场景下我们来观察可能发生的行为:

1、丢失更新:

丢失更新估计是所有数据库用户都不想发生的情况,什么是丢失更新呢?丢失更新是当2个或两个以上的用户进程同时读取同样的数据后又企图修改原来的数据时就会发生。好在上述场景下,大厅LED显示牌显示当前库存1000,这时同时有两个客户上门了,AMM和BMM满面春风接待,比如AMM卖出1个,BMM 呢卖出了10个,AMM处理完业务后赶紧把LED显示数修改为1000-1=999个,几乎同一时间BMM处理完自己的业务后习惯性的把LED显示数修改为1000-10=990个,这时老板从后场过来,看着LED有点不爽,大吼一声:现在还有多少存货呀?,AMM说我卖了1个,BMM说我是10个,不过两个人都傻眼了,LED显示怎么是990呢?原来BMM在更改时把AMM做的更改搞丢了,这就是丢失更新。显然对老板和营业员来说都是必须回避不能发生的事。

2、脏读

很显然,在上面的例子里因为AMM和BMM事先因为不知道对方已经修改了柜台存货,所以才造成了存货数目显示错误,出了问题我们要想办法解决问题,英明的老板说了,你们随便哪个在谈一笔生意时先把客户意向购卖石头数扣掉,如果最后客户不要你再改回头,两个MM对老板的英明决定表示等赞同,可是问题还是发生了,怎么回事呢,还是假设柜台存货1000个石头,AMM有一笔生意正在谈着,顾客意向要600块石头,AMM赶紧把LED显示修改为400。这时BMM也很兴奋因为她已经谈成一笔700块石头的生意,所以呢BMM抬头一看,好嘛,还有400块可卖,完了BMM的生意做不成了,只好向客户表达歉意。BMM只能让老板进货,可是老板一看LED显示还有1000块怎么你的700块生意做不成了呢?哦,因为最后AMM的600块生意没做成。嘿嘿,也就是BMM 错误的读取了AMM修改的数据,完成了一次―脏读‖操作。脏读也就是一个用户进程读取了另一个用户进程修改过但没有正式提交的数据,这时导致了数据不一样的情形发生了。因为A用户进程是无法确认另一个B用户进程在自己提交数据前是否修改过数据,这是数据库系统默认情况下必须回避的。

3、不可重复读

不可重复读又称不一致分析,不过,个人以为似乎不一致分析更让人好理解一点,但是大部分地方称不可重复读。不可重复读是指一个用户进程两次读取数据得到不同样的数据。比如那个英明的老板吧,他知道要盘点,掌握库存的变化,忙得満头大汗,终于计出库存数来,比如说1000吧,或是当他跑到大厅一看LED

显示牌却只有了900,显然这一次的检查库存的过程中两次得到库存数不一样,原因就是AMM在老板从后场走到前场的过程中做了一担生意,卖出100块。嘿嘿,老板气又不是不气又不是,这AMM真可爱,做生意挺两下呀!显然在一个用户进程两次读取数据间隔内另一个用户进程修改了数据,这就是不可重复读。

4、幻影

幻影,嘿嘿,我们不是经常无视BS自己的人吗?你无视他并不代表他不BS你吧,这个BS你的人就成了幻影,嘿嘿开个玩笑。这种情况多数在查询带谓词时结果集内部分数据变化的时候发生,如果谓词限定下在一个交易里两次同一查询的结果集不同,那些不同的行或行集就是幻影。比方说英明的老板到大厅走走,顺便请大家吃饭,数数人数,BMM,。。。。一路数过去,发现有10人,呵呵,正好一桌,,通知好她们后老板回办会室拿人民币,回到前场看见AMM,再一数11人,晕,刚才怎么看到AMM?AMM也知道了老板请客没数到他,很是生气,这时AMM就成了幻影。

以上是四种并发副作用只是一个交易事务里或事务间可能发生的异常的非一致

的数据行为(记好并发副作用和不一致的数据行为术语,这在以后会经常提及),其实还是有好多的行为是我们所期望的,那么我们期望的行为是什么呢,下面我们在事务里来介绍。我们可以通过隔离级别来设定一个合适级别以决定上述上种数据行为哪些是允许的。那什么是交易事务,什么又是隔离等级呢?

三、事务

事务是数据库一笔交易的基本单元,存于两种并发模型中。又分为显式事务和隐式事务。显式事务是显式的开始一个事务并显式的滚回或提交事务,除了显式的事务还有隐式的了,隐式事务是数据库自己根据情况完成的事务处理,如单独的select、update、delete、select语句。

作为一个事务,它能保证数据库的数据一致性及重做。提到事务不得不提及事务的ACID属性:原子性、一致性、隔离性及持久性。不管是显式还是隐式的,都必须维持这四个属性。

原子性:一个事务是一个整体,要不全部提交,要不全部中止。意思就是要不全部成功提交到数据,要不全部回滚恢复事务开始前的状态。比方我们做一个入库操作,在这个事务里,审核入库单和修改库存作为一个整体,要不单据变成审核过同时库存增加相应的值,要不就是单据未审核同时库存不变。

一致性:一致性要求事务保证数据在逻辑上正确,处理的结果不是一个不确定的状态,什么是不确定状态呢,比如说我们完成一个库存减少的操作,如果没有一个出货单据那么这个库存的当前修改就是一个不确定状态,因为你无法知道减少的东东到哪儿去了。

隔离性:这个隔离和锁定有关,以后在说锁的过程中会提到这些,你先记住这个就行。

持久性:持久很显然是要求正确提交的修改必须保证长久存在,不会因为关机或掉电把这笔交易丢掉。进行中的事务发生故障那事务就完全撤销,像没有发生一样,如果事务提交的确认已经反馈给应用程序发生故障,那么这些日志利用先写技术,在启动恢复阶段自动完成相应的动作保证事务的持久性。(这个在前面的引擎组件有过介绍哦。)

四、隔离等级

首先来说说隔离,隔离是一个事务必须与其他事务所进行的资源或数据更改相隔开,显然隔离等级就是相隔的程度了吧。在说隔离级别不得不提及锁的概念,但是在本单不提及锁,在以后听章节里再作说明,大家只要有个印象就行。在这儿我们必须明白两件事:

1,隔离级别不会影响进程获得数据修改的排它锁,并且这个锁会保存到事务结束。相对于读进程来说,隔离级别就是对读操作的一个保护级别,保护读操作受其它事务影响的程序。

2,较低的隔离级别可以增强许多用户同时访问数据的能力,但也增加了用户可能遇到的并发副作用(例如脏读或丢失更新)的数量。相反,较高的隔离级别减少了用户可能遇到的并发副作用,却需要太多的系统资源及一个事务阻塞其他事务的可能性。

应平衡应用程序的完整性要求与相应隔离级别的系统开销,在此基础上选择相应的隔离级别。最高隔离级别(可序列化)保证事务在每次重复读取操作时都能准确检索到相同的数据,但需要通过执行某种级别的锁定来完成此操作,而锁定可能会影响其他用户进程。最低隔离级别(未提交读)可以检索其他事务已经修改但未提交的数据。在未提交读中,所有并发副作用都可能发生,但因为没有读锁定或修改阻塞读取,所以开销最少。

不同的隔离级别决定我们有哪些数据副作用可以发生,而并发模型决定不同隔离等级下如何来限制这些数据行为或如何协调这数据行为。好,那我们来关注一下不同隔离等级下如何限制这些行为的发生。

未提交读(uncommitted Read):字面理解一下,修改了的未提交数据可以读取。准确点:一个用户进程可以读取另一个用户进程修改却未提交的数据。SQL SERVER对这个等级下的读操作不需要获得任何锁就可以读取数据,因为不需要锁所以不会和其它任何进程互相阻塞,自然而然能读取其它进程修改了的却未提交数据。显然这不是我们理想的一种模式,但是它却有了高并发性,因为读操作没有锁不会影响其它进程的读或写操作。在这种级别下,除了丢失更新(上一讲中的数据可能发生的行为)外,其它行为都有可能发生,冒着数据不一致的风险来避免修改的进程阻塞读取的进程,事务的一致性肯定是得不到保障,显然这是消极并发模式下的回避阻塞频繁的一种解决方案。未提交读那肯定是不适合于股票、金融系统的,但是在一些趋势分析的系统里,要求的只是一种走向,准确性可以不是那么严格时,这个级别因并发性能超强成为首选。

已提交读(Read Committed):它和未提交读相反,已提交读级别保证一个进程不可能读到另一个进程修改但未提交的数据。这个级别是引擎默认的级别,也是2005乐观并发模式下支持的级别,也就是说已提交读可是乐观的也可以是悲观的,那究竟当前库是属于哪个并发模型下的已提交读呢,这取决于一个READ_COMMITED_SNAPSHOT数据库配置项,并且缺省是悲观并发控制的。这个配置项决定已提交读级别下事务使用锁定还是行版本控制,并很显然行版本控制是乐观并发模式,锁定是悲观并发模式。我们来点角本看看:

--设置已提交读隔离使用行版本控制

ALTER DATABASE testcsdn SET READ_COMMITTED_SNAPSHOT ON

GO

--查看当前已提交读隔离并发模型

select name,database_id,is_read_committed_snapshot_on f rom sy s.databases

/*

name database_id is_read_committed_snapshot_on

-------------------- ----------- -----------------------------

master 1 0

tempdb 2 0

model 3 0

msdb 4 0

ReportServ er$SQL2005 5 0

ReportServ er$SQL2005TempDB 6 0

TestCsdn 7 1 --current

(7 行受影响)

*/

--设置已提交读隔离使用锁定

ALTER DATABASE testcsdn SET READ_COMMITTED_SNAPSHOT OFF

GO

--查看已提交读隔离并发模型

select name,database_id,is_read_committed_snapshot_on f rom sy s.databases

/*

name database_id is_read_committed_snapshot_on

-------------------- ----------- -----------------------------

master 1 0

tempdb 2 0

model 3 0

msdb 4 0

ReportServ er$SQL2005 5 0

ReportServ er$SQL2005TempDB 6 0

TestCsdn 7 0 --curret

(7 行受影响)

*/

已提交读在逻辑上保证了不会读到不实际存在的数据。悲观并发下的已提交读,当进程要修改数据时会在数据行上申请排它锁,其它进程(无论是读还是写)必须等到排它锁释放才可以使用这些数据。如果进程仅是读取数据时会使用共享锁,其它进程虽然可以读取数据但是无法更新数据,必须等到共离锁释放(共享锁在数据处理完即释放,比如行共享锁在当前数据行数据处理完就自动释放,不会在整个事务内保留发。)。乐观并发的已提交读,也确保不会读到未提交的数据,不是通过锁定的方式来实现,而是通过行版本控制器生成行的提前交的数据版本,被修改的数据虽然仍然锁定,但是其它进程可以可以读取更新前版本数据。

可重复读(Repeatable Read):这也是一个悲观并发的级别。可重复读比已提交读要求更严格,在已提交读的基础上增加了一个限制:获取的共享锁保留到事务结束。在这个限制下,进程在一个事务里两交次读取的数据一致,也就是不会读取到其它进程修改了数据。在这儿我们提到共享锁会保留到事务结束,那得申明一下无论哪种级别及并发模型,排它锁是一定要保留到事务结束的。在可重复读级别共享锁同样也会保留到事务结束。那么这种对数据安全的保证是通过增加共享保留的开销为代价的,也就是只要开始一个事务,其它

用户进程是不可能修改数据的,显而易见的系统的并发性和性能必然下降。这似乎是我们想像中的一种级别,虽然这个级别暂时无法回避幻影读,而且我们也默许并发及性能下降,那只有对程序员对事务的控制有严格的要求:事务要短并尽量不要人为因素的干扰,减少潜在的锁竞争。

快照(SnapShot):乐观并发级别。这是2005新增加的一个隔离级别。快照级别与使用乐观并发的已提交读差不多,差别在于行版控制器里的数据版本有多早,这个在以后讲锁时再说。这个级别保证了一个事务读取的数据是事务开始时就在数据库逻辑上确认并符合一致性的数据。读操作不会要求共享锁定,如果要求的数据已经排它,就会通过行版本控制器读取最近的符合一致性的数据。

可串行化:是目前最严谨、最健壮的一个级别,属于悲观并发。它防止幻影的发生,回避了以前所有意外行为的发生。可串行化意味着系统按进程进入队列的顺序依次、序列化的执行的结果与事务同时运行得到一致的结果。这个最健壮的级别显然共享锁也是随事务开始随事务结束,并通过锁定部分不存在的数据(即索引键范围锁定)来回避幻影的发生。

在前面的两篇里我从纯理论上把事务相关的知识作了一个梳理,有人看了一定觉得无味了吧,好这一篇我们加入一点T-SQL语句把前面所说有东东关联起来,我们人为产生锁定来理解不同的意外数据行为在不同隔离等级下的表现,顺便再重温一下意外数据行及隔离等级,让大家对交易事务有一个直观的认识。

在进行实例前不得不先介绍一点锁的知识,注意这儿只是简单的说一下,不作深入讨论。我们根据用户访问资源的行为先归纳出几种锁,这几种锁在下面的实例里会出现,它们为:共享锁定、排它锁定、更新锁定及用意向这个限定词限定的三种锁(意向共享、意向排它、意向更新),当当然还有其它的模式,我们在下一篇再说。意向锁的存在是解决死锁的发生,保证进程在申请锁定前确定当前数据是否存在不兼容性的锁定。

先对上面提到的锁作一个简单的描述,更详细的下面再说。

共享锁定发生在查询记录时,直观就是我们select啦,但是并不是只有select才有共享锁定。一个查询记录的语句必须在没有与共享锁定互斥锁定存在或等待互斥锁定结束后,才能设置共享锁定并提取数据(互斥不互斥就是锁的兼容性,这在以后再说明)。

排它锁定发生在对数据增加、删除、修改时,事务开始以后语句申请并设置排它锁定(前提是没有其它互斥锁定存在),以明确告知其它进程对当前数据不可以查询或修改,等待事务结束后其它进程才可以查询或修改。

更新锁定是一个介于共享与排它之间的中继锁定,比如我们带where条件的update语句,在查询要更新的记录时是设置共享锁定,当要更新数据时这时锁定必须由共享锁定升级成更新锁定继而升级为排它锁定,当排它锁定设置成功才可以进行数据修改操作。显然也是要要求在锁升级的过程中没有互斥锁定的存在。简单的理解更新锁定是一个中继闸一样,把升级成排它锁定进程―序列化‖,以解决死锁。最后重点说明一下,数据更新阶段是要对数据排它锁定不是更新锁定,不要被字面意思训导哦。

最后说一下在上述锁定模式下的互斥,共享锁定只与排它锁定互斥,更新锁定只与共享锁定不互斥。

在进行具体实例前我们一定要有一个工具来对我们实例过程进行监控,好,下面我写了一个过程,在需要时直接调用就行,过程如下:

Create Proc sp_us_lockinf o

---------------------------------------------------------------------

-- Author : Happy Fly Stone

-- Date : 2009-10-03 15:30:00

-- BLOG : https://www.doczj.com/doc/ab7293332.html,/happyfly stone

-- 申明:请保留作者信息,转载注明出处

---------------------------------------------------------------------

AS

BEGIN

SELECT

DB_NAME(t1.resource_database_id) AS [数据库名],

t1.resource_ty pe AS [资源类型],

-- t1.request_ty pe AS [请求类型],

t1.request_status AS [请求状态],

-- t1.resource_description AS [资源说明],

CASE t1.request_owner_ty pe WHEN 'TRANSACTION' THEN '事务所有'

WHEN 'CURSOR' THEN '游标所有'

WHEN 'SESSION' THEN '用户会话所有'

WHEN 'SHARED_TRANSACTION_WORKSPACE' THEN '事务工作区的共享所有'

WHEN 'EXCLUSIVE_TRANSAC TION_WORKSPACE' THEN '事务工作区的独占所有'

ELSE ''

END AS [拥有请求的实体类型],

CASE WHEN T1.resource_ty pe = 'OBJECT'

THEN OBJECT_NAME(T1.resource_ASsociated_entity_id)

ELSE T1.resource_ty pe+':'+ISNULL(LTRIM(T1.resource_ASsociated_entity_id),'')

END AS [锁定的对象],

t4.[name] AS [索引],

t1.request_mode AS [锁定类型],

t1.request_session_id AS [当前spid],

t2.blocking_session_id AS [锁定spid],

-- t3.snapshot_isolation_state AS [快照隔离状态], t3.snapshot_isolation_state_desc AS [快照隔离状态描述], t3.is_read_committed_snapshot_on AS [已提交读快照隔离]

FROM

sy s.dm_tran_locks AS t1

lef t join

sy s.dm_os_waiting_tasks AS t2

ON

t1.lock_owner_address = t2.resource_address

lef t join

sy s.databases AS t3

ON t1.resource_database_id = t3.database_id

lef t join

(

SELECT rsc_text,rsc_indid,rsc_objid,b.[name]

FROM

sy s.syslockinf o a

JOIN

sy s.indexes b

ON a.rsc_indid = b.index_id and b.object_id = a.rsc_objid) t4 ON t1.resource_description = t4.rsc_text

END

GO

/*

调用示例:exec sp_us_lockinf o

*/

exec sp_us_lockinf o

/*

*/

drop proc sp_us_lockinf o

最后介绍一个隔离等级设置命令:

SET TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED

| READ COMMITTED

| REPEATABLE READ

| SNAPSHOT

| SERIALIZABLE}[;]

好,下面开始实例―快乐‖之旅了。

五、隔离等级实例

测试数据准备:

CREATE DATABASE testcsdn;

GO

CREATE TABLE TA(TCID INT PRIMARY KEY,TCNAME VARCHAR(20))

INSERT TA SELEC T 1,'AA'

INSERT TA SELEC T 2,'AA'

INSERT TA SELEC T 3,'AA'

INSERT TA SELEC T 4,'BB'

INSERT TA SELEC T 5,'CC'

INSERT TA SELEC T 6,'DD'

INSERT TA SELEC T 7,'DD'

GO

约定:以下提及的查询N,都是打开一个新连接执行查询

1、未提交读(uncommitted Read)

概念回顾:未提交读是最低等级的隔离,允许其它进程读取本进程未提交的数据行,也就是读取数据时不设置共享锁定直接读取,忽略已经存在的互斥锁定。很显然未提交读这种隔离级别不会造成丢失更新,但是其它意外行为还是可以发生的。它和select 加锁定提示NOLOCK效果相当。

测试实例:

查询一:

SELECT * FROM TA WHERE TCID = 1

BEGIN TRAN

UPDATE TA

SET TCNAME = 'TA'

WHERE TCID = 1

--COMMIT TRAN --Don't commit

SELECT * FROM TA WHERE TCID = 1

SELECT @@SPID

/*

tcid Tcname

----------- --------------------

1 AA

(1 行受影响)

(1 行受影响)

tcid Tcname

----------- --------------------

1 TA

(1 行受影响)

SPID

54

(1 行受影响)

*/

查询二:

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

SELECT * FROM TA WHERE TCID = 1

/*

tcid Tcname

----------- --------------------

1 TA

(1 行受影响)

*/

--显然未提交读模式我们读到SPID=54未提交的数据。

查询三:

SELECT * FROM TA WHERE TCID = 1

--查询一直进行中…… 无结果

--因为缺省下已提交读级别,所以修改数据设置了排它锁定必须等到SPID=54的事务结束查询四:

--查看当前的锁定信息

exec sp_us_lockinfo

*/

这个时候如果我们回头到查询一里执行commit tran ,你会发现查询三会得到结果,并且是查询一修改后的结果,如果你改用rollback ,那么结果就是原来的值不变,这个你们自己再测试。

1、已提交读(Read Committed)

概念回顾:已提交读是SQL SERVER的缺省隔离级别,悲观模型下是用锁定,乐观模型下使用行版本控制器。这个设置可以通过SET READ_CIMMITTED_SNAPSHOT来修改。在悲观模型下对于读取来说设置共享锁定仅阻止排它锁定,并在数据读取结束自动释放,其它进程方可进行修改操作。也就是说读不会阻止其它进程设置共享及更新锁定,仅阻止排它锁定。在悲观模型下对于修改数据来说设置排锁定阻止所有锁定请示,必须等到排它锁定释放。这个级别的隔离解决了脏读的意外行为。

A、READ_COMMITTED_SNAPSHOT为OFF的情况(缺省)

查询一:

BEGIN TRAN

--用锁定提示模拟共享锁定,并强制共享锁定持续到事务结束SELECT * FROM TA with(holdlock) WHERE TCID = 1

--COMMIT TRAN --Don't commit

SELECT @@SPID

/*

tcid Tcname

----------- --------------------

1 CA

(1 行受影响)

------

54

(1 行受影响)

*/

查询二:悲观模型下已提交读级别

SET TRANSACTION ISOLATION LEVEL READ COMMI TTED UPDATE TA

SET TCNAME = 'TA'

--查询一直没有结果,显然我们验证了共享锁定阻止了排它锁定。查询三:

exec sp_us_lockinf o

--结果大家自己运行看结果。

II、修改数据测试

查询一:

SELECT * FROM TA WHERE TCID = 1

BEGIN TRAN

UPDATE TA

SET TCNAME = 'READ COMMITTED LOCK'

WHERE TCID = 1

--COMMIT TRAN --Don't commit

SELECT @@SPID

/*

tcid Tcname

----------- --------------------

1 TA

(1 行受影响)

54

(1 行受影响)

*/

查询二:

SET TRANSACTION ISOLATION LEVEL READ COMMI TTED SELECT * FROM TA WHERE TCID = 1

/*

--查询一直进行中……被锁定无结果

--修改数据设置了排它锁定必须等到SPID=54的事务结束

*/

查询三:

exec sp_us_lockinf o

/*

*/

A、READ_COMMITTED_SNAPSHOT为ON的情况

先修改当前当前库的READ_COMMITTED_SNAPSHOT为ON ALTER DATABASE TESTCSDN

SET READ_COMMI TTED_SNAPSHOT ON

GO

查询一:

SELECT * FROM TA WHERE TCID = 1

BEGIN TRAN

UPDATE TA

SET TCNAME = 'READ COMMITTED SNAP'

WHERE TCID = 1

--COMMIT TRAN --Don't commit

SELECT @@SPID

/*

TCID TCNAME

----------- --------------------

1 AA

(1 行受影响)

(1 行受影响)

------

56

(1 行受影响)

*/

查询二:因为启用行版本控制器来锁定数据,保证其它进程读取到虽然被排它锁定但在事务开始前已经提交的保证一致性的数据。SET TRANSACTION ISOLATION LEVEL READ COMMI TTED

SELECT * FROM TA WHERE TCID = 1

/*

TCID TCNAME

----------- --------------------

1 AA

(1 行受影响)

*/

查询三:

exec sp_us_lockinf o

/*

*/

3、可重复读(Repeatable Read)

概念回顾:可重复读等级比已提交读多了一个约定:所有的共享锁定持续到事务结束,不是在读取完数据就释放。数据被设置了共享锁定后其它进程只能进行查询与增加不能更改,显然这个级别的隔离对程序有了更高的要求,因为可能因长时间的共享锁定影响系统的并发性能,增加死锁发生的机率。很显然是解决了不可重复读的意外行为。

数据测试:

查询一:

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ

BEGIN TRAN

SELECT * FROM TA WHERE TCID = 1 --可重复查询,并且读不到未提交的数据

--COMMIT TRAN --Don't commit

SELECT @@SPID

/*

tcid Tcname

----------- --------------------

1 READ COMMITTED LOCK

(1 行受影响)

SQLServer的简介及发展历程

S Q L S e r v e r的简介及发展历程SQL简介 SYSTEMR开发的一种查询语言,它的前身是SQUARE语言。SQL语言结构简洁,功能强大,简单易学,所以自从IBM 语言作为查询语言。 织,负责开发美国的商务和通讯标准。ANSI同时也是ISO和InternationalElectrotechnicalCommission(IEC)的 ANSI随之发布的相应标准是ANSISQL-92。ANSISQL-92有时被称为ANSISQL。尽管不同的关系数据库使用的SQL版本有一些差异,但大多数都遵循ANSISQL标准。SQLServer使用ANSISQL-92的扩展集,称为T-SQL,其遵循ANSI 制定的SQL-92标准。 SQL发展历史 1970:E.J.Codd发表了关系数据库理论(relationaldatabasetheory); 1974-79:IBM以Codd的理论为基础开发了“Sequel”,并重命名为"SQL"; 1979:Oracle发布了商业版SQL 1981-84:出现了其他商业版本,分别来自IBM(DB2),DataGeneral(DG/SQL),RelationalTechnology(INGRES); SQL/86:ANSI跟ISO的第一个标准; SQL/89:增加了引用完整性(referentialintegrity); SQL/92(akaSQL2):被数据库管理系统(DBMS)生产商广发接受; 包括oids; SQL/2003:包含了XML相关内容,自动生成列值(columnvalues); 2005-09-30:“Dataisthenextgenerationinside...SQListhenewHTML”!TimO'eilly提出了Web2.0理念,称数据将是核心,SQL将成为“新的HTML"; SQL/2006:定义了SQL与XML(包含XQuery)的关联应用; 2006:Sun公司将以SQL基础的数据库管理系统嵌入JavaV6 2007:SQLServer2008(Katmi)在过去的SQL2005基础上增强了它的安全性,主要在:简单的数据加密,外键管理,增强了审查,改进了数据库镜像,加强了可支持性。 SQLServer的基本信息 SQLServer是一个关系数据库管理系统。它最初是由Microsoft、Sybase和Ashton-Tate三家公司共同开发的,于1988年推出了第一个OS/2版本。在WindowsNT推出后,Microsoft与Sybase在SQLServer的开发上就分道扬镳了,Microsoft将SQLServer移植到WindowsNT系统上,专注于开发推广SQLServer的WindowsNT版本。Sybase则较专注于SQLServer在UNIX?操作系统上的应用。数据库引擎是SQLServer系统的核心服务,负责完成数据的存储、处理和安全管理。

sqlserver2005分割字符串,循环输出示例

create function f_splitstr(@source varchar(500),@split varchar(5)) returns @temp table(tid varchar(50)) as begin declare @ch as varchar(50) set @source=@source+@split while(@source<>'') begin set @ch=left(@source,charindex(',',@source,1)-1) insert @temp values(@ch) set @source=stuff(@source,1,charindex(',',@source,1),'') end return end --select tid from dbo.f_splitstr('xxxxxxx,ttttt,yyyyyy,ererer',',') --select getdate() declare @i int,@countNum int, @para varchar(50) declare tid_cursor CURSOR for select tid from dbo.f_splitstr('xxxxxxx,ttttt,yyyyyy,ererer',',') open tid_cursor FETCH NEXT FROM tid_cursor into @para WHILE@@FETCH_STATUS= 0 BEGIN print @para FETCH NEXT FROM tid_cursor into @para END; CLOSE tid_cursor DEALLOCATE tid_cursor GO

Oracle的事务及锁

1、事务的概念: 事务是一个基本的逻辑单元,它作为一个整体要么全部执行要么全部不执行。 2、事务的特性: 原子性:事务是处理的一个原子单位,每一个操作不可拆分,它要么全部执行成功,要么全部都不执行。 一致性:指事务完成时,必须使所有的数据在整体上不变。 隔离性:各事务之间相互隔离,此事务的执行不受其他并发事务执行的干扰。 持续性:指事务对数据库的改变应是持续存在的,不会因故障而发生丢失。 3、从功能是上划分,sql语言分为DDL、DML和DCL: 3.1DDL(Data Definition Language,数据定义语言): 用于定义和管理数据库中的所有对象的语言,如:create创建表空间、alter修改表空间、drop 删除表空间 3.2:DML(Data manipulation Language,数据操作语言): 处理数据等操作,如:insert插入数据、delete删除数据、update修改数据、select查询数据3.3:DCL(Data Control Language,数据控制语言): 授予或回收访问数据库的权限,控制数据库操作事务发生的时间及效果,对数据库实行监视,如:grant授权,rollback回滚,commit提交 4、事务的开始及结束: 一个事务可以由一条DDL语句单独组成或多条DML语句共同组成。一个事务从执行第一条sql语句开始,在它被提交或被回滚时结束。事务的提交可以是显式提交:用commit命令直接完成;也可以是提交隐式提交:用sql语句间接完成提交,这些语句有:alter,audit,comment,create,disconnect,drop,exit,grant,noaudit,quit,revoke,rename,会话终止等;还可以是自动提交:set autocommit on或set autocommit immediate设置为自动提交,则在插入、删除、修改语句执行后自动提交,使用set autocommit off可以取消自动提交,show autocommit可以查看自动提交是否打开。事务的回滚使用rollback;语句,可以为事务设置保存点,如:savepoint point1,然后使用rollback to [savepoint] point1回到保存点point1,若在point1后又设置了一个保存点savepoint point2,则在rollback to point1后将不能再回滚到point2,因为point2在point1的后面,point1的保存点不存在point2。 5、事务的并发性与一致性: 并发性:多个用户可以在同一时刻访问相同的数据。 一致性:保证并发性的同时,每个用户能得到一致的数据视图。 并发执行事务时,可能发生如下情况: ①脏读:某个事务读取了其他未提交事务修改过的数据。 脏读示例:提交读隔离级别可防止脏读,但不能防止不可重复读 ②不可重复读:某个事务读取一次数据后,其他事务修改了这些数据并进行了提交,这样当该事务重新读取这些数据时,就会得到与前一次读取不一致的结果。简单的说,就是同样的条件,你读取过的数据,再次读取时发现值不一样了。 不可重复读示例:可重复读隔离级别可防止脏读和不可重复读

事务并发控制中的两段锁和可串行化冲突图的对比

文章编号:1000-2375(2005)01-0019-05 事务并发控制中的两段锁和 可串行化冲突图的对比 金 蓉,李跃新 (湖北大学数学与计算机科学学院,湖北武汉430062) 摘 要:数据库中并发操作一般分为数据级和事务级两种,由于资源的竞争可能引起数据级的冲突和事 务级的冲突,因此需要对并发执行的事务转化为某个可串行化调度,从而确保数据库的一致性.目前并发控制的方法有很多,从锁和非锁机制两个方面分析了两段锁和可串行化冲突图两种并发控制的规则和数据结构及分类,并从事务的冲突可串行化方面和结构上分析了各自的性能和优缺点. 关键词:锁;两段锁协议;可串行化冲突图 中图分类号:TP311 文献标志码:A 收稿日期:2004-03-25 作者简介:金 蓉(1979-  ),女,硕士生1 引 言 数据库中的并发操作一般分为数据级和事务级两种,一方面在微观数据级上有数据对象的读(Read )操作和写(Write )操作,另一方面在宏观事务级上有事务的操作原语:终止(Abort ),开始(Begin ),提交(C ommit ),结束(End ),实质上事务中包含着对一系列数据对象的操作,因为一个事务系统主要由3个部分构成:数据项集、对数据项集的操作和控制事务存取数据的管理器(我们称为事务管理器T M ).并发控制的作用是正确协调同一时间里多个事务对数据库的并发操作,解决资源竞争问题以保证数据库的一致性和完整性. 并发控制是通过调度来确保事务的并发执行的效果等同于没有并发执行时的执行效果,也就是使事务的并发执行调度等价于事务的某个可串行化调度,从而确保数据库的一致性.可串行化简单的说就是一个并发操作等效于某个串行执行的效果,也即有相同的输出结果,与串行操作对数据库有同样的效果. 冲突有数据级的冲突和事务级的冲突,数据间的冲突体现在数据库中同时对相同的数据对象操作,事务间的冲突是由事务的数据相关性及在共享数据对象上的交互作用而引起的,通常用事务的“冲突关系”来表示. 定义1 数据对象d 上的两个操作p 、q 是“冲突”的,记为CT (d ,p ,q ),当且仅当S (S (s ,p ),q )≠S (S (s ,q ),p )∨R (s ,p )≠R (S (s ,q ),p )∨R (s ,q )≠R (S (s ,p ),q ).其中,S (s ,p )和R (s ,p )分别表示操作p 对d 的给定状态s 所产生的结果状态和结果输出(返回). 由定义可知,两个或多个数据操作产生冲突的条件是1)它们属于不同的事务;2)都访问数据库中相同的数据对象;3)并且至少有一个是写操作否则就不会产生冲突. 定义2 两个事务t 1、t 2是“冲突”的,记为t 1CR t 2,是指它们包含了(至少)一对冲突操作.即对于任何t 1≠t 2,t 1CR t 2,当且仅当?d 、?p ,q (p (d )∈t 1∧q (d )∈t 2∧CT (d ,p ,q ). 事务间的冲突归根结底集中在数据操作的冲突上,因此解决冲突最初的方法是对数据对象采用锁机制,而锁可以分为读锁和写锁,当数据对象加了读锁后可以再加读锁但不能加写锁,因此读锁是共享的,当数据对象加了写锁后就不能加其他任何锁,因此写锁是排它的,显然读锁较写锁的并发度高. 第27卷第1期2005年3月湖北大学学报(自然科学版)Journal of Hubei University (Natural Science ) V ol.27 N o.1 Mar.,2005

熟悉SQLserver2005系统

西北师范大学计算机科学与工程学院学生实验报告 学号201271040109 专业软件工程班级软件工程1班姓名郭宏乐 课程类型 课程名称熟悉SQLserver2005系 统 实验名称熟悉SQLserver2005系统 实验目的:1:熟悉SQLserver2005系统. 2:学会安装SQLserver2005系统。 3学会运用SQLserver2005系统。 实验内容: 1实验步骤: (1)SQLserver2005安装: 安装过SQL Server的人可能知道,它的有些服务要依赖于IIS,所以为了保证数据库的顺利安装,先启用IIS服务吧!Win7比XP好的一点是:启用IIS功能无需借助系统安装盘了,只要在控制面板里启用即可,如图: step1

step2 第三步需要注意的是,选中红框中的复选项,分别为“Internet Information Services 可承载的Web 核心”、“Web 管理工具”和“万维网服务”,这里我不确定“Web 管理工具”是否需要,因为我选中它们的父节点“Internet 信息服务”后选中了它的一些子项,多选总比少选全面,需要将它们的子项全部选中才显示为“√”,否则显示为“■”,记住,一定要显示为“√”才行,效果就和step3一样就可以了!点击确定后会出现线面的框框

如果我们不启用IIS功能,在后续安装SQL Server时会遇见如图画面 到此,IIS功能就算启用完成了,下面开始安装SQL Server 安装文件解压后是一个ISO的镜像,其实是一个DVD文件,将两张光盘合并到一起了,所以你的电脑需要安装虚拟光驱,虚拟光驱不会用请先百度一下,我就不在这里赘述了。 首先启动虚拟光驱软件,把SQL Server的镜像加载进来,如图

SQLServer2005函数大全

SQL Server 2005 函数大全 字符串函数 (2) 日期和时间函数 (3) 日期部分 (5) 数学函数 (6) 数据类型转换函数 (7) 日期类型数据转换为字符数据类型的日期格式的部分样式表 (8) 系统函数 (11) 排名函数 (11) 聚合函数 (12)

字符串函数 表达式:是常量、变量、列或函数等与运算符的任意组合。以下参数中表达式类型是指表达式经运算后返回的值的类型 函数名称参数示例说明 ascii (字符串表达式) select ascii('abc') 返回 97返回字符串中最左侧的字符的ASCII码。 char(整数表达式) select char(100) 返回 d 把ASCII 码转换为字符。 介于0 和255 之间的整数。如果该整数表达式不在此范围内,将返回NULL 值。 charindex (字符串表达式1,字符串表达式 2[,整数表达式]) select charindex('ab','BCabTabD')返回3 select charindex('ab','BCabTabD',4)返回6 在字符串2中查找字符串1,如果存在返回第一个匹配的 位置,如果不存在返回0。如果字符串1和字符串2中有一个 是null则返回null。 可以指定在字符串2中查找的起始位置。 difference (字符串表达式1,字符串表达式2) select difference('Green','Greene')返回4 返回一个0到4的整数值,指示两个字符表达式的之间的相似程度。0 表示几乎不同或完全不同,4表示几乎相同或完全相同。注意相似并不代表相等 left (字符串表达式,整数表达式) select left('abcdefg',2) 返回 ab返回字符串中从左边开始指定个数的字符。 right (字符串表达式,整数表达式) select right('abcdefg',2) 返回fg返回字符串中从右边开始指定个数的字符。 len(字符串表达式) select len('abcdefg')返回 7 select len('abcdefg ') 返回7 返回指定字符串表达式的字符数,其中不包含尾随空格。lower (字符串表达式) select lower('ABCDEF')返回 abcdef返回大写字符数据转换为小写的字符表达式。 upper (字符串表达式) select upper('abcdef')返回 ABCDEF返回小写字符数据转换为大写的字符表达式。 ltrim (字符串表达式) select ltrim(' abc')返回 abc返回删除了前导空格之后的字符表达式。 rtrim(字符串表达式) select rtrim('abc ')返回 abc返回删除了尾随空格之后的字符表达式。 patindex (字符串表达式1,字符串表达式2) select patindex('%ab%','123ab456')返回4 select patindex('ab%','123ab456')返回0 select patindex('___ab%','123ab456')返回1 select patindex('___ab_','123ab456')返回0 在字符串表达式1中可以使用通配符,此字符串的第一个 字符和最后一个字符通常是%。 %表示任意多个字符,_表示任意字符 返回字符串表达式2中字符串表达式1所指定模式第一次出现 的起始位置。没有找到返回0 reverse (字符串表达式) select reverse('abcde')返回 edcba返回指定字符串反转后的新字符串space (整数表达式) select'a'+space(2)+'b' 返回 a b返回由指定数目的空格组成的字符串。

SQLServer2005完全卸载全攻略

SQLSERVER 2005卸载方法 SQL SERVER 2005不象SERVER 2000所有组件都汇总在一起,所以卸载时特别麻烦,如果不按正常的方法卸载,重新安装是不可能安装上去的。因为SQL SERVER 2005组件都是分散的,所以,必须一个一个的卸载,且要用到两个附加工具(Windows Installer Clean Up.(msicuu2.exe) 文件和SRVINSTW.exe文件),方法如下: 1.如其它软件卸载时一样,打开《控制面板》-新增删除程式 注意:卸载顺序,反向卸载: Microsoft SQL Server VSS Writer Microsoft SQL Server Setup Support Files(English) Microsoft SQL Server Native Client Microsoft SQL Server 2005 Books Online(English) Microsoft SQL Server 2005 Backward compatibillty Microsoft SQL Server 2005

2.安装Windows Installer Clean Up.(msicuu2.exe文件)。安装完后运行 选定下面条目,然后按《Remove》: Microsoft SQL Server VSS Writer Microsoft SQL Server Setup Support Files(English) Microsoft SQL Server Native Client Microsoft SQL Server 2005 Tools Microsoft SQL Server 2005 Books Online(English) Microsoft SQL Server 2005 Backward compatibillty Microsoft SQL Server 2005 3.运行SRVINSTW.exe文件,如图:

数据库锁的概念

锁 锁是网络数据库中的一个非常重要的概念,它主要用于多用户环境下保证数据库完整性和一致性。各种大型数据库所采用的锁的基本理论是一致的,但在具体实现上各有差别。目前,大多数数据库管理系统都或多或少具有自我调节、自我管理的功能,因此很多用户实际上不清楚锁的理论和所用数据库中锁的具体实现。 Microsoft SQL Server(以下简称SQL Server)作为一种中小型数据库管理系统,已经得到了广泛的应用,该系统更强调由系统来管理锁。在用户有SQL请求时,系统分析请求,自动在满足锁定条件和系统性能之间为数据库加上适当的锁,同时系统在运行期间常常自动进行优化处理,实行动态加锁。对于一般的用户而言,通过系统的自动锁定管理机制基本可以满足使用要求,但如果对数据安全、数据库完整性和一致性有特殊要求,就必须自己控制数据库的锁定和解锁,这就需要了解SQL Server的锁机制,掌握数据库锁定方法。 锁的多粒度性以及锁升级 数据库中的锁是指一种软件机制,用来指示某个用户(也即进程会话,下同)已经占用了某种资源,从而防止其他用户做出影响本用户的数据修改或导致数据库数据的非完整性和非一致性。这儿所谓资源,主要指用户可以操作的数据行、索引以及数据表等。根据资源的不同,锁有多粒度(multigranular)的概念,也就是指可以锁定的资源的层次。SQL Server 中能够锁定的资源粒度包括:数据库、表、区域、页面、键值(指带有索引的行数据)、行标识符(RID,即表中的单行数据)。 采用多粒度锁的重要用途是用来支持并发操作和保证数据的完整性。SQL Server根据用户的请求,做出分析后自动给数据库加上合适的锁。假设某用户只操作一个表中的部分行数据,系统可能会只添加几个行锁(RID)或页面锁,这样可以尽可能多地支持多用户的并发操作。但是,如果用户事务中频繁对某个表中的多条记录操作,将导致对该表的许多记录行都加上了行级锁,数据库系统中锁的数目会急剧增加,这样就加重了系统负荷,影响系统性能。因此,在数据库系统中,一般都支持锁升级(lock escalation)。所谓锁升级是指调整锁的粒度,将多个低粒度的锁替换成少数的更高粒度的锁,以此来降低系统负荷。在SQL Server中当一个事务中的锁较多,达到锁升级门限时,系统自动将行级锁和页面锁升级为表级锁。特别值得注意的是,在SQL Server中,锁的升级门限以及锁升级是由系统自动来确定的,不需要用户设置。 锁的模式和兼容性 在数据库中加锁时,除了可以对不同的资源加锁,还可以使用不同程度的加锁方式,即锁有多种模式,SQL Server中锁模式包括: 1.共享锁 SQL Server中,共享锁用于所有的只读数据操作。共享锁是非独占的,允许多个并发事务读取其锁定的资源。默认情况下,数据被读取后,SQL Server立即释放共享锁。例如,执行查询“SELECT * FROM my_table”时,首先锁定第一页,读取之后,释放对第一页的锁定,然后锁定第二页。这样,就允许在读操作过程中,修改未被锁定的第一页。但是,事务隔离级

SQLServer2005查看所有存储过程

如果你想更好的了解SQL Server 2005列出所有存储过程的实际操作的相关内容的话,如果你想更好的了解SQL Server 2005列出所有存储过程的实际操作的相关内容的话,下面的文章你不妨浏览,望你能会获得自己想要的东西。 对于数据库管理员来说,可以经常想了解一些之前未听说过的存储过程,特别是无文档类型的存储过程。或许是用这些存储过程,能够简化日常的数据管理。 对于数据库管理员来说,可以经常想了解一些之前未听说过的存储过程,特别是无文档类型的存储过程。或许是用这些存储过程,能够简化日常的数据管理。 为了查找这些存储过程,你可以花时间在互联网搜索,查看一些你还未知道的存储过程,也许在一两个小时您可能会发现你想要...也许你很幸运的找到,其他人在他们的文章中列出所有的存储过程,函数和视图,并介绍了如何使用这些存储过程。 但其实,您可以在一分钟之内就可以自己列出这些存储过程、函数和视图的清单!这份名单甚至包括SQL Server中所有无文档的存储过程。通过这个清单,你就可以确定你所想要找的存储过程。 SQL Server 2005实际上保存了所有存储过程的列表,包括有文档的、无文档的,甚至是用户自定义的!所有这些信息,都包含在系统表中。最简单的方法是使用一个系统视图,特别是sys.all_objects这个视图来查阅。 您也可以使用sys.procedures目录视图,但我的测试结果,发现这个视图会过滤掉一些储存过程。 您也可以使用系统储存过程sp_stored_procedures返回当前环境中的存储过程列表,但这个存储过程同样也限制了存储过程返回值。 通过对比,我觉得:如果想获得SQL Server 2005中所有的储存程序,建议使用sys.all_objects 这个系统视图,sys.Procedures或sp_Stored_Procedures这两个视图会因为某些未知原因,过滤掉一些内容,造成信息不全。 存储过程信息是存储在各自用户数据库中的系统表中的。SQL Server 2005保存了存储过程的唯一标识信息,如存储过程的名称、创建时间、修改时间、是否来自微软等等。 如何确保所有的用户数据库都能够自动创建这些存储过程呢? 当SQL Server部署完成后,微软提供的存储过程,是保存在master数据库中的。当您新建一个数据库时,master数据库将作为模板数据库,因此,master数据库中的所有存储过程将自动创建到你所新建的数据库中。 如果你想创建一个存储过程,并希望能够自动分发到所有的数据库中,你可以在master数据库中建立该存储过程,这样之后新创建的数据库中,将自动包含你新建的这个存储过程;但对于之前已经存在的数据库,你仍需要到每个数据库中手动创建这个存储过程。

spring事务锁

事务的传播行为和隔离级别[transaction behavior and isolated level] Spring中事务的定义: 一、Propagation : key属性确定代理应该给哪个方法增加事务行为。这样的属性最重要的部份是传播行为。有以下选项可供使用: PROPAGA TION_REQUIRED--支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。 PROPAGA TION_SUPPORTS--支持当前事务,如果当前没有事务,就以非事务方式执行。PROPAGA TION_MANDA TORY--支持当前事务,如果当前没有事务,就抛出异常。PROPAGA TION_REQUIRES_NEW--新建事务,如果当前存在事务,把当前事务挂起。PROPAGA TION_NOT_SUPPORTED--以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。 PROPAGA TION_NEVER--以非事务方式执行,如果当前存在事务,则抛出异常。 很多人看到事务的传播行为属性都不甚了解,我昨晚看了j2ee without ejb的时候,看到这里也不了解,甚至重新翻起数据库系统的教材书,但是也没有找到对这个的分析。今天搜索,找到一篇极好的分析文章,虽然这篇文章是重点分析PROPAGA TION_REQUIRED 和PROPAGA TION_REQUIRED_NESTED的 解惑spring 嵌套事务 /** * @author 王政 * @date 2006-11-24 * @note 转载自https://www.doczj.com/doc/ab7293332.html,/topic/35907?page=1 */ ********TransactionDefinition 接口定义******************* /** * Support a current transaction, create a new one if none exists. * Analogous to EJB transaction attribute of the same name. * This is typically the default setting of a transaction definition. */ int PROPAGATION_REQUIRED = 0; /** * Support a current transaction, execute non-transactionally if none exists. * Analogous to EJB transaction attribute of the same name. * Note: For transaction managers with transaction synchronization,

sqlserver2005双机热备

SQL Server 2005 双机热备的实现 摘自:北京洪鑫基业科技发展有限公司 测试环境: 1、宿主机 硬件配置:PIV2.4G/1.5G-DDR400/80G-PATA-7200pm/8139C-NIC 操作系统:Microsoft Windows XP Pro With SP2 ENU 虚拟平台:VMware GSX 3.2.1 2、VirtualHost Microsoft Cluster NodeA 硬件配置:PIV2.4G/512M/10G/vlance-NIC/vmxnet-NIC 操作系统:Microsoft Windows Server 2003 EE With SP1 CHS 网卡信息:vlance-NIC:10M 全速半双工/HeartBeat/IP192.168.236.250 vmxnet-NIC:1000M全速全双工 /Public/IP192.168.199.250/GW192.168.199.2/DNS192.168.199.250/WINS192.168.199.250 承载服务:DC+DNS+WINS+IIS 3、VirtualHost Microsoft Cluster NodeB 硬件配置:PIV2.4G/512M/10G/vlance-NIC/vmxnet-NIC 操作系统:Microsoft Windows Server 2003 EE With SP1 CHS

网卡信息:vlance-NIC:10M全速半双工/HeartBeat/IP192.168.236.251 vmxnet-NIC:1000M全速全双 工/Public/IP192.168.199.251/GW192.168.199.2/DNS192.168.199.251/WINS192.168.199.251 承载服务:DC+DNS+WINS+IIS 4、Virtual 4G Pln:Qdisk500M/Sdisk3500M 注意:本次测试将仲裁盘和资源盘放在了一起,实际中最佳的做法应当单独配置一个物理磁盘作仲裁使用,为提高安全性还应该为仲裁磁盘配置RAID1。 5、MSCS IP 192.168.199.200 目标实现:成功部署SQL Server 2005群集/HostName SQL2005/IP192.168.199.201 群集实施: 1、我手上的SQL2005为企业中文版2CD。首先放入第一张盘,点击“服务器组件、工具、联机丛书和示例”开始SQL2005的群集安装,安装程序会自动检测当前是否为群集环境并为群集安装准备。小提示:MSCS默认环境下,群集组资源中缺少MSDTC组件,所以需要先添加MSDTC后再开始SQL2005的群集安装,否则会出现警告并停止!

第12章 事务与锁机制

第12章事务与锁机制 一、选择题 1.下面选项中,()不是数据库事务必须具备的特征。 A.原子性B.一致性C.孤立性D.适时性 2.MySQL创建事务的一般步骤是()。 A.初始化事务、创建事务、应用SELECT查看事务、提交事务 B.初始化事务、应用SELECT查看事务、应用事务、提交事务 C.初始化事务、创建事务、应用事务、提交事务 D.创建事务、应用事务、应用SELECT查看事务、提交事务 3.事务的开始和结束命令分别是()。 A.START TRANSACTION、ROLLBACK B.START TRANSACTION、COMMIT C.START TRANSACTION、ROLLBACK或者COMMIT D.START TRANSACTION、BREAK 4.下面()选项不是ANSI/ISO SQL规范提供的隔离级别。 A.SERIALIZABLE B.REPEATABLE READ C.READ ROLLBACK D.READ UNCOMMITTED 5.下面控制事务自动提交的命令,正确的是()。 A.SET AUTOCOMMIT=0; B.SET AUTOCOMMIT=1; C.SELECT @@autocommit; D.SELECT @@tx_isolation; 6.在MySQL中,可以使用()命令开启一个事务。 A.START TRANSACTION B.BEGIN C.BEGIN WORK D.以上都是 7.下列关于读锁和写锁的区别描述正确的是()。 A.两个读锁是兼容的 B.一个读锁和一个写锁是不兼容的 25

26 C.两个写锁也是不兼容的 D.以上都正确 8.下列关于锁策略的描述错误的是()。 A.表级锁是MySQL中最基本的锁策略,而且是开销最小的策略。 B.行级锁可以最大程度地支持并发处理,同时也带来了最大的锁开销。 C.一个读锁请求可能会被插入到写锁队列的前面。 D.在MySQL中,每种存储引擎都可以实现自己的锁策略和锁粒度。 9.下列()语句可以将事务的隔离级别设置为读未提交数据。 A.SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; B.SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE; C.SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; D.SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; 10.下列关于行级锁的描述错误的是()。 A.事务中的行级锁的生命周期从加锁开始,直到事务提交或者回滚才会被释放。 B.InnoDB表只能设置行级锁。 C.为了延长行级锁的生命周期,可以采用开启事务实现。 D.InnoDB表的行级锁的粒度仅仅是受查询语句或者更新语句影响的记录。 二、填空题 1.数据库事务必须具备___________________、___________________、___________________和___________________特征(简称ACID)。 2.在当前连接中,可以通过将_________________________变量设置为_________,来禁用自动提交功能。 3.在MySQL中,可以使用MySQL的_______________________命令查询_______________________变量的值,以确定MySQL的自动提交功能是否关闭。 4.在MySQL中,应用_______________________命令来标记一个事务的开始。 5.使用________________________命令实现在事务中设置一个回退点。 6.在处理并发读或者写时,可以通过实现________________锁和_______________锁来解决问题。 7.在MySQL中采用__________________存储引擎的数据表,并不支持COMMIT(提交)和ROLLBACK (回滚)命令。 8.为指定数据表添加锁定可以使用__________________________________________语句来实现,释放对表的锁定状态可以使用__________________________语句来实现。 9.以写方式锁定数据表可以使用_________________________________语句来实现。 10.在MySQL中,可以通过执行______________________________________命令设置事务的隔离级别。

如果某个事务已锁定一个资源,而另一事务又需要访问

锁机制防止多人存取资源时不至于混乱,而且防止阻塞。 一、锁的类型 如果某个事务已锁定一个资源,而另一事务又需要访问该资源,那么 Microsoft SQL Server 2005会根据第一个事务所用锁定模式的兼容性确定是否授予第二个锁。 对于已锁定的资源,只能施加兼容类型的锁。例如,如果持有排他 (X) 锁,那么,除非在第一个事务结束时释放该 X 锁,否则其他事务将无法获取该资源的共享锁、升级锁或排他锁。相反,如果已向某个资源应用共享 (S) 锁,那么,即使第一个事务尚未完成,其他事务也可以获取该资源的共享锁或升级 (U) 锁。但是,只有在释放共享锁之后,其他事务才可以获取排他锁。 资源的锁定模式有一个兼容性矩阵,可以显示哪些锁与在同一资源上获取的其他锁兼容,并按照锁强度递增的顺序列出这些锁。 下表显示了请求的锁定模式及其与现有锁定模式的兼容性: 请求的模式 IS S U IX SIX X 意向共享 (IS) 是 是 是 是 是 否 共享 (S) 是 是 是 否 否 否 升级 (U) 是 是 否 否 否 否 意向排他 (IX) 是 否 否 是 否 否 意向排他共享 (SIX) 是 否 否 否 否 否

排他 (X) 否 否 否 否 否 否 注意: IX 锁与 IX 锁定模式兼容,因为 IX 指示其意向是更新某些行,而不是更新所有行。只要不会影响其他事务正在更新的行,那么也允许其他事务读取或更新某些行。 Microsoft SQL Server Database Engine使用不同的锁模式锁定资源,这些锁模式确定了并发事务访问资源的方式。 下表显示了数据库引擎使用的资源锁模式。 锁模式 说明 共享 (S) 用于不更改或不更新数据的读取操作,如 SELECT 语句。 更新 (U) 用于可更新的资源中。防止当多个会话在读取、锁定以及随后可能进行的资源更新时发生常见形式的死锁。 排他 (X) 用于数据修改操作,例如 INSERT、UPDATE 或 DELETE。确保不会同时对同一资源进行多重更新。 意向 用于建立锁的层次结构。意向锁的类型有:意向共享 (IS)、意向排他 (IX) 以及意向排他共享 (SIX)。 架构 在执行依赖于表架构的操作时使用。架构锁的类型有:架构修改 (Sch-M) 和架构稳定性 (Sch-S)。 大容量更新 (BU) 在向表进行大容量数据复制且指定了 TABLOCK 提示时使用。 键范围 当使用可序列化事务隔离级别时保护查询读取的行的范围。确保再次运行查询时其他事务无法插入符合可序列化事务的查询的行。 共享锁 共享锁(S 锁)允许并发事务在封闭式并发控制(请参阅并发控制的类型)下读取 (SELECT) 资源。资源上存在共享锁(S 锁)时,任何

SQLserver锁和事务隔离级别的比较与使用

SQLserver锁和事务隔离级别的比较与使用 对象 ①锁:每条SQL语句 ②隔离:事务 锁 ① 并发问题 丢失更新 未确认的读取(脏读) 不一致的分析(非重复读):多次读取相同的数据(行)不一致(其他用户更改update) 幻像读:多次读取有不存在和新增的数据(其他用户插入insert或删除delete) 隔离级别 幻像说明 隔离级别脏读不可重 复读取 未提交读(read uncommitted)是是是如果其他事务更新,不管是否提交,立即执行 提交读(read committed默认)否是是读取提交过的数据。如果其他事务更新没提交,则等待可重复读(repeatable read)否否是查询期间,不允许其他事务update 可串行读(serializable)否否否查询期间,不允许其他事务insert或delete

对数据已经具有排他锁(只能有一个),其他的事务就不能对锁定的数据获取共享锁和排他锁(即排他锁与共享锁不能兼容,更多信息请查看锁兼容性),在此特别强调一下锁定的数据,因为有的资料上讲解到“一个连接写的时候,另一个连接可以写”,实际上写的这种情况是各个连接的读写的数据不是相同的行,也就是说各个连接锁定的数据不同。 根据以上分析,我们总结为六个字为“共享读,排他写”。 了解了锁的情况之后,又涉及到一个问题。事务究竟要保持锁多久呢? 一般来说,共享锁的锁定时间与事务的隔离级别有关,如果隔离级别为Read Committed 的默认级别,只在读取(select)的期间保持锁定,即在查询出数据以后就释放了锁;如果隔离级别为更高的Repeatable read或Serializable,直到事务结束才释放锁。另说明,如果select语句中指定了HoldLock提示,则也要等到事务结束才释放锁。 排他锁直到事务结束才释放。 做出了以上分析,现在我们可能会存在这样的疑问,到底在执行SQL语句的时候发出什么样的锁呢,这就由事务的隔离级别决定了。一般情况,读语句(select)发出共享锁,写语句(update,insert,delete)发出排他锁。但是,如果这样不能满足我们的要求怎么办呢,有没有更多选择呢,别急,SQLserver为我们提供了锁定提示的概念。 锁定提示对SQL语句进行特别指定,这个指定将覆盖事务的隔离级别。下面对各个锁定提示分别予以介绍(更多资料请查看SQLserver的联机帮助),笔者做出了以下分类。类型1 ①READUNCOMMITTED:不发出锁 ②READCOMMITTED:发出共享锁,保持到读取结束 ③REPEATABLEREAD:发出共享锁,保持到事务结束 ④SERIALIZABLE:发出共享锁,保持到事务结束 类型2 ①NOLOCK:不发出锁。等同于READUNCOMMITTED ②HOLDLOCK:发出共享锁,保持到事务结束。等同于SERIALIZABLE ③XLOCK:发出排他锁,保持到事务结束。 ④UPDLOCK:发出更新锁,保持到事务事务结束。(更新锁:不阻塞别的事物,允许别的 事物读数据(即更新锁可与共享锁兼容),但他确保自上次读取数据后数据没有被更新)⑤READPAST:发出共享锁,但跳过锁定行,它不会被阻塞。适用条件:提交读的隔离级别, 行级锁,select语句中。 类型3 ①ROWLOCK:行级锁 ②PAGLOCK:页级锁 ③TABLOCK:表锁 ④TABLOCKX:表排他锁 讲解完锁后,下面结合一个具体实例,具体看一下锁的使用。 在很多系统中,经常会遇到这种情况,要保持一个编号的唯一,如会计软件中的凭证的编号。一种编号的处理是这样的,把表中的最大编号保存到表中,然后在这个编号上累加,形成新的编号。这个过程对并发处理要求非常高,下面我们就来模拟这个过程,看如何保持编号的唯一性。 新建一张表code来保存凭证的最大编号。字段如下:编号:bh(numeric(18,0)),凭证表名pinzheng(varchar(50)) 假设表中有这样的一条记录: Bh Pinzheng

SQLserver简介

Introduction to SQL Server By Samuel Relational databases have been around for 30 years, but they were not the original kind ofdatabase, nor are they the newest kind of database. XML and object-oriented data structures haveevolved in recent years. But relational databases are still by far the most popular kind of database available and will be for some time to come. SQL is the abbreviation of Structured Query Language and it is for relational databases, as the title indicates this is only for fresher who has just started the carrier or who is waiting to open up the carrier in the application programming side. But that does not mean this article is a tutorial for a fresher who does not know anything about SQL.This article is meant for who already have a little knowledge in SQL and want toimprove it. What Does SQL Do? F irst, SQL is the premier tool for viewing information from a relational database. It doesn’t just give you a data dump. SQL gives you sophisticated tools to summarize, consolidate, and calculate from the data. Using table relationships, data can be combined from multiple tables in a number of ways. With a properly designed database, SQL can answer practically any question about the data. Second, SQL provides commands to manipulate the data in a relational database. Records can be updated and added to or deleted from a table. Here is SQL as a database language really shines. Procedural programming languages, such as BASIC, might require several lines of code to update a record in a database table. In addition, procedural programming languages would have to use some sort of looping structure to repeat this process on every record. SQL operates on an entire set of records all at the same time. SQL is like haiku for programmers; often a dozen words or fewer can delete or change thousands of records. Finally, SQL is a complete data definition language (DDL). The database itself can be created along with all tables, fields, primary keys, and relationships. Add to that the record insert commands, and you can have a complete database and all its data expressed in programming code. This greatly enhances a database programmer’s ability to work remotely or to port data enhancements among various installations. The prerequisite for learning SQL is knowledge in Discrete Mathematics (Set Theory,Relations and Functions). Although it is not necessary to learn all the

相关主题
文本预览
相关文档 最新文档