日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[Todo] 乐观悲观锁,自旋互斥锁等等

發布時間:2023/12/4 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [Todo] 乐观悲观锁,自旋互斥锁等等 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

樂觀鎖、悲觀鎖、要實踐

http://chenzhou123520.iteye.com/blog/1860954 《mysql悲觀鎖總結和實踐》

http://chenzhou123520.iteye.com/blog/1863407 《mysql樂觀鎖總結和實踐》

http://outofmemory.cn/sql/optimistic-lock-and-pessimistic-lock

?

注意,以下的表里面的列名,一定要用 `` 反引號來包括。

mysql> create table `t_goods` ( -> `id` bigint(11) NOT NULL AUTO_INCREMENT, -> `status` bigint(11) DEFAULT 0, -> `name` varchar(32) DEFAULT NULL, -> `version` bigint(11) DEFAULT 1, -> PRIMARY KEY (`id`) -> ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; Query OK, 0 rows affected (0.13 sec)

?

mysql> insert into t_goods (`name`) values ('weapon'); Query OK, 1 row affected (0.07 sec)mysql> insert into t_goods (`name`) values ('equipment'); Query OK, 1 row affected (0.10 sec)

mysql> select * from t_goods;
+----+--------+-----------+---------+
| id | status | name | version |
+----+--------+-----------+---------+
| 1 | 0 | weapon | 1 |
| 2 | 0 | equipment | 1 |
+----+--------+-----------+---------+
2 rows in set (0.00 sec)

?

實驗1,select for update 指定主鍵,只鎖行:

首先要關閉autocommit:

mysql> set autocommit=0; Query OK, 0 rows affected (0.00 sec)mysql> show variables like 'autocommit'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | autocommit | OFF | +---------------+-------+ 1 row in set (0.00 sec)

如果不關閉,經過實驗,的確不會相互影響。

關閉autocommit之后,普通的sql不放在事務里面也可以。

console A:mysql> select * from t_goods where id = 1 for update; +----+--------+--------+---------+ | id | status | name | version | +----+--------+--------+---------+ | 1 | 0 | weapon | 1 | +----+--------+--------+---------+ 1 row in set (0.00 sec)console B: mysql> select * from t_goods where id = 1; +----+--------+--------+---------+ | id | status | name | version | +----+--------+--------+---------+ | 1 | 0 | weapon | 1 | +----+--------+--------+---------+ 1 row in set (0.00 sec)mysql> select * from t_goods where id = 2 for update; +----+--------+-----------+---------+ | id | status | name | version | +----+--------+-----------+---------+ | 2 | 0 | equipment | 1 | +----+--------+-----------+---------+ 1 row in set (0.00 sec)mysql> select * from t_goods where id = 1 for update; ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

?

可以看出,不加for update不影響,加了for update不是同一行,不影響(僅對于主鍵查詢有關)。

?

實驗2,select for update 指定非主鍵,鎖全部:

Console A: mysql> select * from t_goods where name = 'weapon' for update; +----+--------+--------+---------+ | id | status | name | version | +----+--------+--------+---------+ | 1 | 0 | weapon | 1 | +----+--------+--------+---------+ 1 row in set (0.00 sec)Console B: mysql> select * from t_goods; +----+--------+-----------+---------+ | id | status | name | version | +----+--------+-----------+---------+ | 1 | 0 | weapon | 1 | | 2 | 0 | equipment | 1 | +----+--------+-----------+---------+ 2 rows in set (0.00 sec)mysql> select * from t_goods where name = 'equipment' for update; ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transactionmysql> select * from t_goods where id = 2 for update; ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

?

實驗3,查詢主鍵沒查到,不鎖:

Console A: mysql> select * from t_goods where id=3 for update; Empty set (0.01 sec)Console B: mysql> select * from t_goods for update; +----+--------+-----------+---------+ | id | status | name | version | +----+--------+-----------+---------+ | 1 | 0 | weapon | 1 | | 2 | 0 | equipment | 1 | +----+--------+-----------+---------+ 2 rows in set (0.00 sec)

說明,主鍵沒查到數據,不加鎖。

?

實驗4,查詢非主鍵,沒查到,鎖全部,table lock.

Console A: mysql> select * from t_goods where name = 'abc' for update; Empty set (0.00 sec)Console B: mysql> select * from t_goods for update; ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transactionmysql> select * from t_goods where id = 1 for update; ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

?

實驗5:查詢主鍵不明確,為范圍,大于小于,只鎖相關的行;

Console A: mysql> select * from t_goods where id > 1 for update; +----+--------+-----------+---------+ | id | status | name | version | +----+--------+-----------+---------+ | 2 | 0 | equipment | 1 | +----+--------+-----------+---------+ 1 row in set (0.00 sec)Console B: mysql> select * from t_goods where id = 1 for update; +----+--------+--------+---------+ | id | status | name | version | +----+--------+--------+---------+ | 1 | 0 | weapon | 1 | +----+--------+--------+---------+ 1 row in set (0.00 sec)mysql> select * from t_goods where id = 2 for update; ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

?

實驗5:查詢主鍵不明確,!=或者<>,鎖全部;

Console A: mysql> select * from t_goods where id != 1 for update; +----+--------+-----------+---------+ | id | status | name | version | +----+--------+-----------+---------+ | 2 | 0 | equipment | 1 | +----+--------+-----------+---------+ 1 row in set (0.00 sec)Console B: mysql> select * from t_goods where id = 1 for update; ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transactionConsole A: mysql> select * from t_goods where id <> 1 for update; +----+--------+-----------+---------+ | id | status | name | version | +----+--------+-----------+---------+ | 2 | 0 | equipment | 1 | +----+--------+-----------+---------+ 1 row in set (0.00 sec)Console B: mysql> select * from t_goods where id = 1 for update; ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

?

實驗6,對于普通索引,也類似于主鍵的效果:

未加索引之前,鎖全表: console A: mysql> select * from t_goods where status = 1 for update; +----+--------+--------+---------+ | id | status | name | version | +----+--------+--------+---------+ | 1 | 1 | weapon | 1 | +----+--------+--------+---------+ 1 row in set (0.00 sec)console B: mysql> select * from t_goods where id = 2 for update; ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction加了索引之后,只鎖行: console A: mysql> alter table t_goods add index index_name(`status`); Query OK, 0 rows affected (0.15 sec) Records: 0 Duplicates: 0 Warnings: 0mysql> select * from t_goods where status = 1 for update; +----+--------+--------+---------+ | id | status | name | version | +----+--------+--------+---------+ | 1 | 1 | weapon | 1 | +----+--------+--------+---------+ 1 row in set (0.00 sec)console B: mysql> select * from t_goods where id = 2 for update; +----+--------+-----------+---------+ | id | status | name | version | +----+--------+-----------+---------+ | 2 | 0 | equipment | 1 | +----+--------+-----------+---------+ 1 row in set (0.00 sec)mysql> select * from t_goods where id = 1 for update; ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

?

樂觀鎖:

從業務層面加鎖,一般是加上version字段,然后sql以如下形式處理:

update t_goods set status=2,version=version+1 where id=#{id} and version=#{version};

?

自旋鎖與互斥鎖

http://blog.csdn.net/a675311/article/details/49096435

自旋鎖就是不聽的忙檢測,拿不到鎖就返回。

pthread中提供的鎖有:pthread_mutex_t, pthread_spinlock_t, pthread_rwlock_t。pthread_mutex_t是互斥鎖,同一瞬間只能有一個線程能夠獲取鎖,其他線程在等待獲取鎖的時候會進入休眠狀態。因此pthread_mutex_t消耗的CPU資源很小,但是性能不高,因為會引起線程切換。 pthread_spinlock_t是自旋鎖,同一瞬間也只能有一個線程能夠獲取鎖,不同的是,其他線程在等待獲取鎖的過程中并不進入睡眠狀態,而是在CPU上進入“自旋”等待。自旋鎖的性能很高,但是只適合對很小的代碼段加鎖(或短期持有的鎖),自旋鎖對CPU的占用相對較高。 pthread_rwlock_t是讀寫鎖,同時可以有多個線程獲得讀鎖,同時只允許有一個線程獲得寫鎖。其他線程在等待鎖的時候同樣會進入睡眠。讀寫鎖在互斥鎖的基礎上,允許多個線程“讀”,在某些場景下能提高性能。 諸如pthread中的pthread_cond_t, pthread_barrier_t, semaphone等,更像是一種同步原語,不屬于單純的鎖。

http://www.cnblogs.com/hdflzh/p/3716156.html

http://blog.csdn.net/pi9nc/article/details/39177343

?

Java鎖相關

http://blog.csdn.net/Evankaka/article/details/44153709 (這一篇要重點看,講了Thread Runnable等)

http://blog.csdn.net/Evankaka/article/details/51866242(Java鎖技術內幕上)

http://blog.csdn.net/evankaka/article/details/51932044(Java鎖技術內幕中)

?

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的[Todo] 乐观悲观锁,自旋互斥锁等等的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。