如果我在表上执行SELECTS,表上的SELECT查询是否有可能将INSERTS阻止到同一表中?
SELECT会在行上共享锁,但不会正确插入吗?
查询是一个LIKE子句-这会阻止插入吗?它有潜力吗?
SELECT * FROM USERS WHERE Description LIKE '%HELLO%'
参考: 我阅读了此回复SQL Server SELECT statements causing blocking,但感到困惑,这将如何阻止插入。
答案 0 :(得分:1)
一般信息-称为SQL Server Concurrency
,在SQL Server
中您会找到两个模型:
回答您的问题-是的,您可以在读取期间阻止任何插入,这称为“悲观并发”。但是,该模型具有特定的属性,您必须小心,因为:
重点是,如果锁持有时间较短,则应仅使用悲观并发 ,而如果使用费用,则应仅使用 如Neeraj所说,每个锁的锁比发生冲突时回滚交易要低。
我建议阅读更多有关同时使用悲观和乐观模型here的隔离级别的信息。
编辑-我在堆栈here上找到了有关隔离级别的非常详细的说明。
答案 1 :(得分:1)
SELECT将对行进行共享锁定,但不会生效 插入正确吗?
不,不完全正确。
当您制作SELECT
时,它可以在shared locks
甚至整个pages
上获取table
,
您可以使用paglock
或tablock
提示自己进行测试(当然,您应该使用repeatable read
或serializable
来查看它们,因为其中的所有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;
在这里看到lock escalation result
,我的查询希望每个locks
超过5000 statement
,因此服务器只用了一个lock
,shared lock
而不是table
INSERT
。
现在,如果您尝试从另一个会话插入此表中的任何行,则您的IX
将被阻止。
这是因为任何插入首先需要获取table
上的IX
和page
上的IX
,但是表上的S
与select
在同一张表上,因此将被阻止。
这样,您的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>
);
}
})
。