【性能测试】基本入门(包含mysql锁)
性能测试要防止走入缓存中,因为一旦走入缓存中,就是进入了理想的情况。
数据库原理可以读这篇文章
http://blog.jobbole.com/100349/
mysql innodb 的select … for update语句
如果另一个事务修改了某一行,但是没有提交,然后使用select … for update进行查询,这时会阻塞掉,直到获取锁超时
(1205, 'Lock wait timeout exceeded; try restarting transaction')
查看mysql innodb锁超时时间,查看当前锁的情况
show status like 'innodb_row_lock%';
+-------------------------------+----------+
| Variable_name | Value |
+-------------------------------+----------+
| Innodb_row_lock_current_waits | 1 |
| Innodb_row_lock_time | 15406545 |
| Innodb_row_lock_time_avg | 49 |
| Innodb_row_lock_time_max | 51229 |
| Innodb_row_lock_waits | 314101 |
+-------------------------------+----------+
- 要验证能够承载的用户数量
- 要确定没有并发问题
通过Http作为性能测试的入口
Dubbo作为性能测试的入口
通过api直连的方式调用dubbo
客户端设置300个线程的时候
Caused by: com.alibaba.dubbo.remoting.RemotingException: Server side(192.168.10.108,31806) threadpool is exhausted ,detail msg:Thread pool is EXHAUSTED! Thread Name: DubboServerHandler-192.168.10.108:31806, Pool Size: 200 (active: 199, core: 200, max: 200, largest: 200), Task: 746213 (completed: 746013), Executor status:(isShutdown:false, isTerminated:false, isTerminating:false), in dubbo://192.168.10.108:31806!
重要的指标
响应时间
mysql
mybatis有没有缓存
show processlist命令(如果您有SUPER权限,您可以看到所有线程。否则,您只能看到您自己的线程)
dubbo有没有缓存?
抽奖活动
流程:
1.查看用户抽奖次数
2. 用户抽奖次数减少一次
3. 抽取奖品,写入奖品记录表
4. 减少奖品库存
5. 告知用户抽奖结果
剩余抽奖次数surplus_amount
我们要验证并发情况下,每次抽奖 surplus_amount 都会减少
数据库引擎类型innodb
show engines;
+--------------------+---------+----------------------------------------------------------------+--------------+--------+------------+
| Engine | Support | Comment | Transactions | XA | Savepoints |
+--------------------+---------+----------------------------------------------------------------+--------------+--------+------------+
| TokuDB | YES | Tokutek TokuDB Storage Engine with Fractal Tree(tm) Technology | YES | YES | YES |
| MRG_MYISAM | YES | Collection of identical MyISAM tables | NO | NO | NO |
| CSV | YES | CSV storage engine | NO | NO | NO |
| BLACKHOLE | YES | /dev/null storage engine (anything you write to it disappears) | NO | NO | NO |
| SPHINX | YES | Sphinx storage engine 2.3.2-dev | NO | NO | NO |
| MEMORY | YES | Hash based, stored in memory, useful for temporary tables | NO | NO | NO |
| ARCHIVE | YES | Archive storage engine | NO | NO | NO |
| MyISAM | YES | MyISAM storage engine | NO | NO | NO |
| PERFORMANCE_SCHEMA | YES | Performance Schema | NO | NO | NO |
| InnoDB | DEFAULT | Supports transactions, row-level locking, and foreign keys | YES | YES | YES |
| FEDERATED | NO | Federated MySQL storage engine | <null> | <null> | <null> |
+--------------------+---------+----------------------------------------------------------------+--------------+--------+------------+
查看事务隔离级别:
SELECT @@tx_isolation +----------------+
| @@tx_isolation |
+----------------+
| READ-COMMITTED |
+----------------+
修改数据库的核心语句<update id="updateAmount">update lottery_chance set surplus_amount=surplus_amount-1 where user_id=#{userId,jdbcType=BIGINT} and activity_id=#{activityId,jdbcType=BIGINT} and surplus_amount>0</update>
测试方法
创建100个线程,每个线程里面调用100次,一共10000次调用, 查看surplus_amount字段
原理是什么?
假设A,B两个事务,在A update的过程中,会加上排他锁,B 要update要获取排他锁,从而保证了不会出现并发问题。
update lottery_chance set surplus_amount=surplus_amount-1 语句会使用排他锁
锁
悲观锁
原理是:
如果一个事务需要一条数据
它就把数据锁住
如果另一个事务也需要这条数据
它就必须要等第一个事务释放这条数据
这个锁叫排他锁。
但是对一个仅仅读取数据的事务使用排他锁非常昂贵,因为这会迫使其它只需要读取相同数据的事务等待。因此就有了另一种锁,共享锁。
共享锁是这样的:
如果一个事务只需要读取数据A
它会给数据A加上『共享锁』并读取
如果第二个事务也需要仅仅读取数据A
它会给数据A加上『共享锁』并读取
如果第三个事务需要修改数据A
它会给数据A加上『排他锁』,但是必须等待另外两个事务释放它们的共享锁。
同样的,如果一块数据被加上排他锁,一个只需要读取该数据的事务必须等待排他锁释放才能给该数据加上共享锁。
mysql加的锁在commit后才会释放
比如开两个窗口,起两个事务,一个update, 另一个update会被block
某种情况下出现的死锁
Exception in thread "Thread-2" java.lang.RuntimeException: org.springframework.dao.DeadlockLoserDataAccessException:
### Error updating database. Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction
### The error may involve defaultParameterMap
### The error occurred while setting parameters
### SQL: update lottery_chance set surplus_amount=surplus_amount-1 where user_id=? and activity_id=? and surplus_amount>0
### Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction
; SQL []; Deadlock found when trying to get lock; try restarting transaction; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction
org.springframework.dao.DeadlockLoserDataAccessException:
### Error updating database. Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction
### The error may involve defaultParameterMap
### The error occurred while setting parameters
### SQL: update lottery_chance set surplus_amount=surplus_amount-1 where user_id=? and activity_id=? and surplus_amount>0
### Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction
; SQL []; Deadlock found when trying to get lock; try restarting transaction; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transactionat org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:263)
并发情况插入两条数据
先查询,不存在的时候插入数据,这个在并发情况下遇到的问题如下:
下面的代码在高并发情况下,数据库里面可能有两条一样的数据
LotteryChanceEntity entity = lotteryChanceDao.selectByUserId(userId);if (entity == null) {entity = new LotteryChanceEntity();entity.setUserId(userId);lotteryChanceDao.insert(entity);}
伪代码
if(oderid != null){//该记录已存在update();
}else{ //写入记录insert();
}
解决方法:
数据库层面添加唯一索引约束
代码层面 :单机可以使用synchronized锁, 分布式可以使用redis setnx锁
插入两条数据可能导致下面的问题
org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or null) to be returned by selectOne(), but found: 2
InnoDB行锁:只有通过索引条件检索数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁!
【性能测试】基本入门(包含mysql锁)相关推荐
- Mysql 锁的机制
2019独角兽企业重金招聘Python工程师标准>>> 引言 数据库锁定机制简单来说就是数据库为了保证数据的一致性而使各种共享资源在被并发访问变得有序所设计的一种规则:对于任何一种数 ...
- 五分钟了解Mysql的行级锁——《深究Mysql锁》
延伸阅读: 三分钟了解Mysql的表级锁 一分钟深入Mysql的意向锁 mysql锁相关讲解及其应用--<深究mysql锁>了解锁前,一定要先看这篇,了解什么是MVCC,如果我们学习锁,没 ...
- 深入理解 MySQL ——锁、事务与并发控制
本文对 MySQL 数据库中有关锁.事务及并发控制的知识及其原理做了系统化的介绍和总结,希望帮助读者能更加深刻地理解 MySQL 中的锁和事务,从而在业务系统开发过程中可以更好地优化与数据库的交互. ...
- mysql 一对多 关联一条最新的数据_不得不会的mysql锁
6. 多表之间的关系 如图,实际业务数据库中的表之间都是有关系的,我们接下来主要要学习的就是如何分析表关系及建立表关系. 分类表 create table category( cid varchar( ...
- mysql锁场景_MySQL死锁系列-常见加锁场景分析
在上一篇文章<锁的类型以及加锁原理>主要总结了 MySQL 锁的类型和模式以及基本的加锁原理,今天我们就从原理走向实战,分析常见 SQL 语句的加锁场景.了解了这几种场景,相信小伙伴们也能 ...
- mysql 并发避免锁表_Yii+MYSQL锁表防止并发情况下重复数据的方法
本文实例讲述了Yii+MYSQL锁表防止并发情况下重复数据的方法.分享给大家供大家参考,具体如下: lock table 读锁定 如果一个线程获得在一个表上的read锁,那么该线程和所有其他线程只能从 ...
- 深入理解 MySQL—锁、事务与并发控制
本文转载自"vivo 互联网技术",已获授权. 本文对 MySQL 数据库中有关锁.事务及并发控制的知识及其原理做了系统化的介绍和总结,希望帮助读者能更加深刻地理解 MySQL 中 ...
- mysql 锁机制及实现原理_MySQL-深入浅出锁分类及实现原理
个人公众号『码农札记』,欢迎关注,查看更多精彩文章. 背景 数据库是一个多用户并发使用的共享资源.当多个并发读写数据时,在数据库中就会产生多个事务同时读写同一数据的情况. 若对并发操作不加控制就可能会 ...
- mysql锁在粒度上分为_mysql锁的简单理解
一.锁 我们通常概念里的锁,是用来处理线程安全问题,锁(latch)的对象是线程,而在mysql中通常所说的锁(lock),是用来实现事务的acid特性的一种手段,也就是锁(lock)的对象是事务,而 ...
最新文章
- 异常-java.util.concurrent.TimeoutException: Futures timed out after [100000 milliseconds]
- mybatis文档笔记
- 【吾日三省吾身】2015.6.03-涅槃行动第十六天
- Java将一段逗号分割的字符串转换成一个数组(亲测)
- TREX搜索的执行最后也是通过HTTP call来完成的
- linux s t i a权限,关于Linux下s、t、i、a权限
- python泰坦尼克号数据预测_使用python预测泰坦尼克号生还
- C/C++ 文件的后缀名
- TensorFlow学习笔记——TensorFlow入门
- AWS环境搭建(六):Linux上部署wowza,并配置ssl证书
- STM32F103 DMA方式GPIO输出
- 大数据如何赋能产品—用户特征分析
- 微信开发 没有认证过的服务号怎么办?微信提供了测试号(开通了认证过的服务号的功能)
- Mac在有S.M.A.R.T错误的情况下安装OSX系统
- win11 删除系统自带输入法
- 使用前端js代码开发了一个图片转ico图标的功能
- 学计算机这么课最大的收获是啥,计算机课程学习心得范文
- 别让你的mongodb宕机了
- 关节空间阻抗控制器设计的个人理解
- 关于栈顶指针初值为-1和0的区别