如果沒有鎖,那麼併發性會更強,但是資料安全性會有問題。因此資料庫會給資料加鎖。
也就是讀寫鎖,共享鎖可以疊加共享鎖但是不能加排他鎖, 排他鎖則不能疊加。
根據隔離級別等等,mysql會隱式的給資料自動加鎖
此外還可以使用share in model, for update 等語句顯示的加鎖
粒度越細,維護鎖的開銷越大,併發性越高,資料越不安全。 通常有如下兩種
- 行鎖
只給一行資料加鎖
- 表鎖
給整張表加鎖, 一般alter table會使用表鎖
mysql為了提高衝突監測效能而存在的一種鎖。是給其上一級所加的鎖,所以在mysql中通常為表鎖。
比如乙個事務,給兩行加了排他鎖,又有乙個事務想要給整個表加共享鎖,這個時候就要去檢視所有的表的行是否有鎖策略不能加共享鎖。 如果有了意向鎖,那麼事務1就能再給兩行加排他鎖的同時,給整個表加ix, 這樣事務2不用遍歷就能知道不可以加s鎖了。
a,b兩個人同時在系統上進行操作,比如要修改乙份訂單。 當a正在修改準備提交前向上廁所,這兒時候b修改完訂單並且提交了。 這個時候a回來了再提交就會出現問題,b的修改被覆蓋了。
- 悲觀鎖
for update, share in model語句
使用悲觀鎖,則會在操作期間全程對資料進行加鎖,其他人不能再次修改。這樣會造成比較長時間的阻塞。
適用於短事務,寫量比較大的情況。
- 樂觀鎖
樂觀鎖通過在資料庫中新增乙個version欄位,操作後給version + 1. 提交時比較,如果比資料庫中的大,則提交。大概的**是:
if(connection.update("update set name='123' where id=1 and version < #current_version#") > 0)
這種適用於讀多,寫少,並且寫有可能會用很長時間的情況。
比如有兩個事物:
事物1
update table1 set name='1'
where id=1;
// sleep 1
update table1 set name='2'
where id=2;
commit;
事物2
update table1 set name='2'
where id=2;
// sleep 2
update table1 set name='1'
where id=1;
commit;
上面的語句如果恰巧一起執行到sleep1 和sleep2,那麼就會造成死鎖。 一般有三種做法解決:
執行select .. from where id between這樣的語句的時候鎖定這一區間,不能插入或者刪除資料,以防止幻讀。
mysql維護乙個系統版本號,每次有新的事物開始的時候遞增。
每行後面儲存兩個隱藏列。 乙個建立時版本號c,乙個刪除時版本號d
set autocommit=0;
begin;
select * from biz_pay_task where id = 1
forupdate;
// wait
commit;
事務2
set autocommit=0;
begin;
select * from biz_pay_task where id = 1
lock
in share mode;
commit;
事務2在執行select lock in share mode的時候會阻塞,知道事務1commit之後才會完成。 mysql 第二天總結
今日回顧 create table 表名 欄位名1 型別 字段附加屬性 欄位名2 型別 字段附加屬性 charset utf8 gbk 表中儲存資料的字元編碼 engine innodb myisam bdb memory 表型別 型別 數字型別 整數 int,tinyint,smallint,me...
MySQL第二天 基礎用法
mysql第二天介紹 sqlsql介紹 sql它的全稱叫 structured query language,結構化的查詢語言。之所以出現這個東西,是為了統一 遮蔽不同資料庫廠商生產資料庫產品之間的差異 簡單的ddl 比如更改表名 alter table 表名 rename 新錶名 更改欄位名 al...
上班第二天
本想坐晚一班車的,誰知道這晚一班的也只是晚了 五 六分鐘,不高興再在站台上等,也只好小跑到車門上去了,果然,八點十分就到了。白天那個困啊 今天的工作內容和昨天一樣,做到後來我實在覺得測的差不多了,想幹些其他的,但這初來乍到的,也不好幹其他的呀,況且領導辦公室就在我旁邊。今天的工作總結有兩點 1 別把...