[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锁技术内幕中)

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/292735.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android之 ListView滑动时不加载图片

listview加载图片优化的功能&#xff0c; 在我们使用新浪微博的时候&#xff0c;细心的同学一定发现了&#xff0c;在滑动的过程中&#xff0c;图片是没有被加载的&#xff0c; 而是在滑动停止时&#xff0c;才加载图片了。 我们今天就做一个这样的效果吧。 我们先考虑两个问题…

C#之Lock

lock 关键字将语句块标记为临界区&#xff0c;方法是获取给定对象的互斥锁&#xff0c;执行语句&#xff0c;然后释放该锁。 class Program{static void Main(string[] args){Thread t new Thread(LockObject.MonitorIncrement);Thread t1new Thread(new ThreadStart(LockObje…

记一次 .NET 某消防物联网 后台服务 内存泄漏分析

一&#xff1a;背景 1. 讲故事去年十月份有位朋友从微信找到我&#xff0c;说他的程序内存要炸掉了。。。截图如下&#xff1a;时间有点久&#xff0c;图片都被清理了&#xff0c;不过有点讽刺的是&#xff0c;自己的程序本身就是做监控的&#xff0c;结果自己出了问题&#xf…

高性能网站建设的最佳实践(二)

原文译自雅虎开发者社区&#xff0c;转载译文请标明出处。关注我的sina微博&#xff0c;共同进步&#xff01;为了让网页响应速度更快Exceptional Performance团队列出了一系列的最佳实践&#xff0c;包括35个最佳实践条目&#xff0c;分成7种类型类。避免重定向标签&#xff1…

python带通配符的字符串匹配_Bash技巧:实例介绍数个参数扩展表达式以处理字符串变量...

Linux 的 bash shell 提供了多种形式的参数扩展表达式&#xff0c;可以获取变量自身的值&#xff0c;或者对变量值进行特定处理得到一个新的值&#xff0c;等等。本篇文章对字符串变量值相关的参数扩展表达式进行汇总说明。假设在 bash 中定义了 filepathexample/subdir/testfi…

幸福手机,给爸妈的高端大气上档次的手机

打造高端老人手机——幸福手机 江苏智联天地科技有限公司历经2年&#xff0c;手机研发投入超过4000万&#xff0c;打造中国第一品牌的高端老人手机&#xff0c;手机将于2014年12月正式对外发布&#xff0c;是国内第一款高端老人手机——幸福手机&#xff08;ThimFone&#xff0…

Fisher–Yates shuffle 算法

简单来说 Fisher–Yates shuffle 算法是一个用来将一个有限集合生成一个随机排列的算法(数组随机排序)。这个算法生成的随机排列是等概率的。同时这个算法非常高效。 Fisher–Yates shuffle 的原始版本,最初描述在 1938 年的 Ronald Fisher(上图) 和 Frank Yates 写的书中…

MASA Framework - EventBus设计

概述利用发布订阅模式来解耦不同架构层级&#xff0c;亦可用于解决隔离业务之间的交互优点&#xff1a;松耦合横切关注点可测试性事件驱动发布订阅模式发布者通过调度中心将消息发送给订阅者。调度中心解决发布与订阅者之间的关系&#xff0c;保证消息可以送达订阅者手中。发布…

Qt经验积累:常见的驱动打包处理方法

Qt对于常见的驱动打包,如数据库,图片等常用的插件驱动.如果处理不好,程序运行不起来,不能加载驱动,处理方法如下:在主程序中加入以下两句话:QString strLibPath(QDir::toNativeSeparators(QApplication::applicationDirPath())QDir::separator()"plugins"); a.addLib…

wireshark-win64-3.4.0安装_这9类轴承的安装方法,你可都知道?有哪些需要注意的呢?...

轴承是当代机械设备中一种重要零部件。随着时间的推移&#xff0c;轴承会发生磨损&#xff0c;合理的安装和使用可以让机械设备减少不必要的安全隐患。前面文章讲了如何拆卸轴承&#xff0c;今天就给大家讲讲各类轴承应该如何安装&#xff01;一、轴承安装前的准备工作轴承的安…

linux之which命令

我们经常在linux要查找某个文件&#xff0c;但不知道放在哪里了&#xff0c;可以使用下面的一些命令来搜索&#xff1a; which 查看可执行文件的位置。 whereis 查看文件的位置。 locate 配合数据库查看文件位置。 find 实际搜寻硬盘查询文…

slidingmenu能否实现菜单页在内容页上方,而不是把内容页挤到一边去????...

问题描述。。。。。。。。。。。。。。。。。。。。。。。。。。。。 解决方案1这样的话 你自己写不就好了 左边菜单view显示出来加一个动画 设置view的透明度 还用什么slidingmenu啊 解决方案2这个效果不是用的slidingmenu吧&#xff0c;自己实现一个 解决方案3对啊&#xff0…

史上最牛数学简史

全世界只有3.14 % 的人关注了爆炸吧知识“中国现代数学之父”华罗庚曾说过宇宙之大&#xff0c;粒子之微火箭之速&#xff0c;化工之巧地球之变&#xff0c;生物之谜日用之繁&#xff0c;无处不用数学回首往昔数学始终伴随我们左右纵横交错的几何、繁琐复杂的运算难以求解的方程…

log4net日志插件的使用

1、安装log4net2、引用3、配置&#xff08;web.config文件&#xff09;<configSections><section name"log4net" type"log4net.Config.Log4NetConfigurationSectionHandler, log4net"/></configSections><log4net><!--信息日志…

源代码提交SOP(Git版)

一、原则1、在维护公共基类、工具类和二方库等可能影响到其他团队成员的代码之前&#xff0c;必须同其他团队成员讨论&#xff0c;达成共识后方可进行维护。2、严格遵守源码签入规范&#xff0c;有助于发现代码漏洞&#xff0c;降低代码合并风险&#xff0c;降低远程仓库代码的…

linux下使用pidcat找bug

第一步&#xff1a; 安装pidcat 第二步&#xff1a; 找到APP的包名比如adb shell ps | grep sangforadb shell pm list package第三步&#xff1a; 在ubuntu终端输入pidcat.py 包名结果&#xff1a;

创建与删除索引

索引是加速查询的主要手段&#xff0c;特别对于涉及多个表的查询更是如此。本节中&#xff0c;将介绍索引的作用、特点&#xff0c;以及创建和删除索引的语法。13.4.1 使用索引优化查询索引是高速定位数据的技术&#xff0c;首先通过一个演示样例来了解其含义及作用&#xff0…

r vector 4 elements_Vector类与Enumeration接口

Vector类用于保存一组对象&#xff0c;由于java不支持动态数组&#xff0c;Vector可以用于实现跟动态数组差不多的功能。如果要将一组对象存放在某种数据结构中&#xff0c;但是不能确定对象的个数时&#xff0c;Vector是一个不错的选择。例&#xff1a;将键盘上输入的一个数字…