最近在数据库上经常遇到死锁问题. 表现的问题有

1. 有一个查询为:

1) 一个复杂的 select 查处一组大数据

2) 使用事务 update 这组数据的状态

为了让锁定的时间变短, 我将这整个大事务切分成了多个小事务, 也就是每次查询并更新 1W 数据变为了每次查询并更新 100 数据, 但是需要查询更新 100 次, 总数据量还是 1W

这样就造成了一个问题, 因为这个 select 是个复杂查询, 这里 100 次 select 使得整个操作时间急剧上升.

所以我认为最好的做法是, 先把 1W 数据用 select 查询出来, 然后 update 操作分组, 例如每次 update 1000, 如果这次事务 update 失败, 则将 update 失败的这些数据从 select 结果集中去掉

2. 有一个大量的结果集更新, 例如 5W 条, 原来我的做法是切分为 10 个小事务, 每次更新 5000 条, 顺序更新

实际上这里没有必要用事务, 因为我对他们没有一致性和原子性要求. 使用事务的好处是效率提高, 因为 MySQL 默认是 autocommit = true, 相当于没条语句是一个事务. 但是使用事务的缺点是 update 的锁的持有时间会加长, 容易造成死锁.

最后的解决方案是使用多线程同时执行, 并且不适用事务, 但是使用 preparedStatement (batch).

最后看看我的测试数据, 一共测试了 10W 的数据

1. 使用 batch 一次性执行完毕, 共耗费 55s
2. 使用多线程并发执行, 每个线程 batch 数量为 5000, 线程池大小是 CPU核数 * 2, 共耗费 11s

3. 不适用 batch, 但是用多线程执行, 每个线程负责 5000 数据插入, 共耗费 24s

4. 使用事务, 但是不用 batch, 使用多线程执行, 每个线程负责 5000 数据, 共耗费 14s

5. 使用事务, 同时使用 batch, 使用多线程, 每个线程 5000 数据, 共耗费 8s

可见使用事务, 同时 batch 效率最高, 但是使用事务会加长锁的持有时间, 这点需要注意

MySQL Batch 与 Transaction的更多相关文章

  1. mysql事务,START TRANSACTION, COMMIT和ROLLBACK,SET AUTOCOMMIT语法

    http://yulei568.blog.163.com/blog/static/135886720071012444422/ MyISAM不支持 START TRANSACTION | BEGIN ...

  2. mysql --batch --skip-column-name --execute 使用

    mysql -h 127.0.0.1 -P 3306 -u root -p -D test --batch --skip-column-name --execute="select * fr ...

  3. Django Mysql SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED

    Django 执行makemigrations  的时候报错: django.db.utils.ProgrammingError: (1064, "You have an error in ...

  4. MySQL存储过程 事务transaction

    MySQL 中,单个 Store Procedure(SP) 不是原子操作,而 Oracle 则是原子的.如下的存储过程,即使语句2 失败,语句 1 仍然会被 commit 到数据库中: create ...

  5. 配置MySQL GTID(Global Transaction IDs)复制

    一.GTID的简介 1.GTID的概述 .全局事物标识:global transaction identifieds. .GTID事物是全局唯一性的,且一个事务对应一个GTID. .一个GTID在一个 ...

  6. mysql & java & spring transaction isolation level

    mysql /*SESSION LEVEL*/ select @@tx_isolation; /*GLOBAL LEVEL*/ select @@global.tx_isolation; select ...

  7. [MySQL] MySQL存储过程 事务transaction 数据表重建

    直接上代码 -- 删除存储过程 DROP PROCEDURE IF EXISTS `renew_message_queue`; -- 添加; 的转义 DELIMITER ;; CREATE PROCE ...

  8. Mysql的transaction实现(转)

    (http://www.blogjava.net/i369/archive/2007/04/29/108906.html) transaction在数据库编程中是一个重要的概念,这样做可以控制对数据库 ...

  9. 学习笔记:The Best of MySQL Forum

    http://mysql.rjweb.org/bestof.html I have tagged many of the better forum threads. 'Better' is based ...

随机推荐

  1. How to Allow MySQL Client to Connect to Remote MySql

    How to Allow MySQL Client to Connect to Remote MySQ By default, MySQL does not allow remote clients ...

  2. mysql的ONLY_FULL_GROUP_BY语义 --转自http://www.wtoutiao.com/p/19dh3ec.html

    执行SET GLOBAL sql_mode = ''; 把sql_mode 改成非only_full_group_by模式.验证是否生效 SELECT @@GLOBAL.sql_mode 或 SELE ...

  3. SQL Server DBA性能优化

    虽然查询速度慢的原因很多,但是如果通过一定的优化,也可以使查询问题得到一定程度的解决. 查询速度慢的原因很多,常见如下几种:1.没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺陷)2. ...

  4. linux shell mysql 数据库主从同步状态检查告警

    需求: 1.监测数据库主从状态 2.获取数据库主要参数 3.可读取配置文件 4.部署位置自适应.   参考资料: http://blog.csdn.net/yf210yf/article/detail ...

  5. 大师教你<部落冲突>如何切换账号

    前提申请两个谷歌账号,账号一和账号二,想要切换账号,只需清除部落冲突在手机上的数据即可.详情请看下文! 1. 第一次登陆,进入游戏后 2. 没有谷歌商店的童鞋,下载谷歌安装器(一键修复)以及VPNFQ ...

  6. FM/PCM与FM/PPM的区别

    FM/PCM的优点:     1 高可靠性和高抗干扰性.大家知道,一般PPM遥控设备都要求在操作时先开发射机后开接收机,先关接收机后关发射机.其原因是在没有发射信号时,接受机会因自身内部的噪音或外界的 ...

  7. 命令别名alias设置

    <转:http://vbird.dic.ksu.edu.tw/linux_basic/0320bash_3.php> 命令别名配置: alias, unalias 命令别名是一个很有趣的东 ...

  8. 将框架的底层改掉,改成一个轻量级的ORM

    公司底层的缺点 1.功能有限,只有增删查改 2.不支持异步 3.不支持懒加载 4.不支持泛型 5.不支持Linq 6.性能没做到最好,比如FirsttOrDefault()只能通过查找select * ...

  9. 57. Jump Game && Jump Game II

    Jump Game Given an array of non-negative integers, you are initially positioned at the first index o ...

  10. 简单实用的Windows命令(一)

    前几天新买了一台笔记本电脑,使用了一下几个简单的查看电脑配置的命令,觉得非常的不错,在此记录一下 一:运行命令的方式有两种 1:使用快捷键WIN+R,然后在弹出的“运行”对话框中输入对应的命令 2:在 ...