选择可以从插入阻止表吗?

时间:2019-09-16 16:02:21

标签: sql-server

如果我在表上执行SELECTS,表上的SELECT查询是否有可能将INSERTS阻止到同一表中?

SELECT会在行上共享锁,但不会正确插入吗?

查询是一个LIKE子句-这会阻止插入吗?它有潜力吗?

SELECT * FROM USERS WHERE Description LIKE '%HELLO%'

参考: 我阅读了此回复SQL Server SELECT statements causing blocking,但感到困惑,这将如何阻止插入。

2 个答案:

答案 0 :(得分:1)

一般信息-称为SQL Server Concurrency,在SQL Server中您会找到两个模型:

  • 悲观的;
  • 乐观。

回答您的问题-是的,您可以在读取期间阻止任何插入,这称为“悲观并发”。但是,该模型具有特定的属性,您必须小心,因为:

  • 正在读取的数据已锁定,因此其他用户无法修改数据;
  • 被修改的数据被锁定,因此其他用户无法读取或修改数据;
  • 由于每个数据访问操作(读/写)都获取一个锁,因此获取的锁数量很高;
  • 作家阻止读者和其他作家。读者会阻止作家。

重点是,如果锁持有时间较短,则应仅使用悲观并发 ,而如果使用费用,则应仅使用 如Neeraj所说,每个锁的锁比发生冲突时回滚交易要低。

我建议阅读更多有关同时使用悲观乐观模型here的隔离级别的信息。

编辑-我在堆栈here上找到了有关隔离级别的非常详细的说明。

答案 1 :(得分:1)

  

SELECT将对行进行共享锁定,但不会生效   插入正确吗?

不,不完全正确。 当您制作SELECT时,它可以在shared locks甚至整个pages上获取table, 您可以使用paglocktablock提示自己进行测试(当然,您应该使用repeatable readserializable来查看它们,因为其中的所有shared locks read committed将在不再需要时被释放。

可以通过以下方式对相同情况进行建模:

if object_id('dbo.t') is not null drop table dbo.t;

select top 10000 cast(row_number() over(order by getdate()) as varchar(10)) as col
into dbo.t
from sys.columns c1 
     cross join sys.columns c2;

set transaction isolation level serializable;

begin tran
    select *
    from dbo.t 
    where col like '%0%';

    select resource_type,
           request_mode,
           count(*) as cnt
    from sys.dm_tran_locks
    where request_session_id = @@spid
    group by resource_type,
             request_mode;

enter image description here

在这里看到lock escalation result,我的查询希望每个locks超过5000 statement,因此服务器只用了一个lockshared lock而不是table INSERT

现在,如果您尝试从另一个会话插入此表中的任何行,则您的IX将被阻止。

这是因为任何插入首先需要获取table上的IXpage上的IX,但是表上的Sselect在同一张表上,因此将被阻止。

这样,您的insert可能会阻止您的sys.dm_tran_locks

要查看服务器上究竟发生了什么,您应该使用session_id过滤后的registerBlockType('materialize-fcd/gallery-block', { title: "Material Gallery - Galleria", icon: 'images-alt', category: 'common', attributes: { images: { type: 'array', default: null }, ids: { type: 'array', default: null }, size: { type: 'string', default: 'full' }, s: { type: 'number', default: 6 }, m: { type: 'number', default: 4 }, l: { type: 'number', default: 3 }, lightbox:{ type: 'string', default: 'gal_'+Math.floor(Math.random() * 9000) } }, edit(props) { const { setAttributes, attributes, } = props; function changeS(newValue) { setAttributes({ s: newValue }) } function changeM(newValue) { setAttributes({ m: newValue }) } function changeL(newValue) { setAttributes({ l: newValue }) } function onChangeSize(value) { setAttributes({ size: value }) } function onChangeLightbox(value) { setAttributes({ lightbox: value }) } function onImagesSelect(imageObject) { var id_array = imageObject.map(image => image.id); setAttributes({ images: imageObject, ids: id_array }) console.log(attributes.images); } var choices = []; if (attributes.images != null) { //ciclo le immagini for(var i in attributes.images){ //ciclo le sizes for (var name in attributes.images[i].sizes) { if (!choices.map(choice=>choice.value).includes(name)){ var choice = { value: name, label: name } if(name == attributes.size) choice.selected = true; choices.push(choice); } } } } var mediaButton = (<MediaUpload onSelect={onImagesSelect} type="image" value={attributes.ids} render={ ({ open}) => { return ( <button onClick={open}> Choose image </button>); } } multiple = 'add' />); var images = []; for (var i in attributes.images) { images.push(<img style={{"max-width" : "150px", "max-height" : "150px"}} src={attributes.images[i].sizes.full.url}/>); } return ([( <InspectorControls> <PanelBody title='Column Size'> <PanelRow> <RangeControl label="Mobile (S)" value={ attributes.s } onChange={changeS} min={ 0 } max={ 12 } /> </PanelRow> <PanelRow> <RangeControl label="Tablets (M)" value={ attributes.m } onChange={changeM} min={ 0 } max={ 12 } /> </PanelRow> <PanelRow> <RangeControl label="Desktops (L)" value={ attributes.l } onChange={changeL} min={ 0 } max={ 12 } /> </PanelRow> </PanelBody> <PanelBody title='Image Size'> <PanelRow> <SelectControl label='Image size:' value={attributes.size} onChange={onChangeSize} options={choices} /> </PanelRow> </PanelBody> <PanelBody title='Lightbox'> <PanelRow> <TextControl label='Gallery ID:' value={attributes.lightbox} onChange={onChangeLightbox} /> </PanelRow> </PanelBody> <PanelBody title='Images'> <PanelRow> {mediaButton} </PanelRow> </PanelBody> </InspectorControls> ),( <div> {attributes.className ?'CLASS: ' + attributes.className : null} {attributes.className ?<br/> : null} {mediaButton} <br/> {attributes.images != null ? images : ''} </div> )]); }, save(props) { const { attributes, className } = props; var images = []; var cols = (props.attributes.s != 0 ? ' s' + props.attributes.s : '') + (props.attributes.m != 0 ? ' m' + props.attributes.m : '') + (props.attributes.l != 0 ? ' l' + props.attributes.l : '') + (props.attributes.className ? ' '+props.attributes.className : ''); for (var i in attributes.images) { images.push( <div class={'col' + cols}> <a sl={(attributes.lightbox == '' || attributes.lightbox == null) ? null : attributes.lightbox} href={attributes.images[i].sizes.full.url} class={(attributes.className ? attributes.className + ' ' : '')+'waves-effect waves-light img gal z-depth-2'}> <img src={attributes.images[i].sizes[attributes.size].url} /> </a> </div> ); } return ( <div class="row"> {images} </div> ); } })