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

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. 使用Visual Studio Code搭建TypeScript开发环境

    使用Visual Studio Code搭建TypeScript开发环境 1.TypeScript是干什么的 ? TypeScript是由微软Anders Hejlsberg(安德斯·海尔斯伯格,也是 ...

  2. [solr] - 索引数据删除

    删除solr索引数据,使用XML有两种写法: 1) <delete><id>1</id></delete> <commit/> 2) < ...

  3. lumen 登陆 注册 demo

    本文将用Lumen来实现一个完整的用户注册.登录及获取用户信息的API. Lumen环境搭建和初始化详细步骤请参考上篇文章<Lumen安装配置使用入门>一文. 一.准备工作 1.Lumen ...

  4. CentOS 6.5 安装 Python3

    1.安装环境 yum -y install gcc zlib-devel make 2.下载python版本 wget http://www.python.org/ftp/python/3.5.1/P ...

  5. 不使用spring的情况下原生java代码两种方式操作mongodb数据库

    由于更改了mongodb3.0数据库的密码,导致这几天storm组对数据进行处理的时候,一直在报mongodb数据库连接不上的异常.   主要原因实际上是和mongodb本身无关的,因为他们改的是配置 ...

  6. PHP使用mysqldump备份数据库(以及还原)

    导出数据实例如下: <?php $mdb_host = $g_c["db"][0]["managertool"]["host"]; / ...

  7. bootstrap-进度条

    <div class="container"> <div class="row"> <div class="col-lg ...

  8. oracle数据库如何创建角色并对角色授予权限

    目标: 1.创建角色test1_role, 授予create session 权限 2.创建角色test2_role,授予create procedure, create sequence, crea ...

  9. html 定位问题

    HTML精确定位:scrollLeft,scrollWidth,clientWidth,offsetWidth scrollHeight: 获取对象的滚动高度. scrollLeft:设置或获取位于对 ...

  10. apache 配置https

    1.生成密钥# openssl genrsa 1024 > server.key这是用128位rsa算法生成密钥,并保存到server.key文件 2.生成证书请求文件# openssl req ...