索引與加鎖
索引對於innodb非常重要,因為它可以讓查詢鎖更少的元組。這點十分重要,因為mysql 5.0中,innodb直到事務提交時才會解鎖。有兩個方面的原因:首先,即使innodb行級鎖的開銷非常高效,記憶體開銷也較小,但不管怎麼樣,還是存在開銷。其次,對不需要的元組的加鎖,會增加鎖的開銷,降低併發性。
innodb僅對需要訪問的元組加鎖,而索引能夠減少innodb訪問的元組數。但是,只有在儲存引擎層過濾掉那些不需要的資料才能達到這種目的。一旦索引不允許innodb那樣做(即達不到過濾的目的),mysql伺服器只能對innodb返回的資料進行where操作,此時,已經無法避免對那些元組加鎖了:innodb已經鎖住那些元組,伺服器無法解鎖了。
來看個例子:
create table actor(
actor_id int unsigned not null auto_increment,
name varchar(16) not null default '',
password varchar(16) not null default '',
primary key(actor_id),
key (name)
) engine=innodb
insert into actor(name,password) values('cat01','1234567');
insert into actor(name,password) values('cat02','1234567');
insert into actor(name,password) values('ddddd','1234567');
insert into actor(name,password) values('aaaaa','1234567');
set autocommit=0;
begin;
select actor_id from actor where actor_id < 4
and actor_id <> 1 for update;
該查詢僅僅返回2---3的資料,實際已經對1---3的資料加上排它鎖了。innodb鎖住元組1是因為mysql的查詢計畫僅使用索引進行範圍查詢(而沒有進行過濾操作,where中第二個條件已經無法使用索引了):
mysql> explain select actor_id from test.actor
-> where actor_id < 4 and actor_id <> 1 for update \g
*************************** 1. row ***************************
id: 1
select_type: ******
table: actor
type: index
possible_keys: primary
key: primary
key_len: 4
ref: null
rows: 4
extra: using where; using index
1 row in set (0.00 sec)
mysql>
表明儲存引擎從索引的起始處開始,獲取所有的行,直到actor_id<4為假,伺服器無法告訴innodb去掉元組1。
為了證明row 1已經被鎖住,我們另外建乙個連線,執行如下操作:
set autocommit=0;
begin;
select actor_id from actor where actor_id = 1 for update;
該查詢會被掛起,直到第乙個連線的事務提交釋放鎖時,才會執行(這種行為對於基於語句的複製(statement-based replication)是必要的)。
如上所示,當使用索引時,innodb會鎖住它不需要的元組。更糟糕的是,如果查詢不能使用索引,mysql會進行全表掃瞄,並鎖住每乙個元組,不管是否真正需要。
單例模式加鎖與不加鎖例項C
1 教科書裡的單例模式 我們都很清楚乙個簡單的單例模式該怎樣去實現 建構函式宣告為private或protect防止被外部函式例項化,內部儲存乙個private static的類指標儲存唯一的例項,例項的動作由乙個public的類方法代勞,該方法也返回單例類唯一的例項。上 12 3 4 5 6 7 ...
oracle中加鎖與解鎖
oracle中的資料在併發操作時,為了防止錯誤的發生可以進行記錄或者資料庫表的加鎖操作。當鎖操作完成時可以進行解鎖操作。資料庫中加鎖有兩種方式,獨佔模式和共享模式。1.獨佔模式,不允許其他會話以任何方式共享鎖定資源,當進行資料庫資料修改時可以使用這種模式。2.共享模式,允許在資料訪問時,併發共同訪問...
Oracle 使用者加鎖與解鎖
檢視使用者狀態 以sysdba身份登入sqlplus sqlplus as sysdba 查詢指定使用者狀態 使用者名稱需要大寫 select username,account status from dba users where username abc 狀態顯示為open,表示使用者狀態正常。...