最近在项目中遇到了一个数据同步的问题

项目部署背景:利用nginx集群式服务器部署,使用唯一的一台数据库服务器,数据库为mysql

问题描述:对一个账户进行更新操作,一个未查明的原因,用户点击更新操作后,未知的原因在后台同时产生了两个request请求,这两个请求并发进行,同时调用存储过程对数据库进行操作,造成了对数据库的重复操作,等于说操作了两次,账户余额变成了负值。

为了重新问题,写了个测试类,多线程调用此存储过程,重现了这个问题

final TaskThreadExecution t = new TaskThreadExecution();ThreadPoolExecutor threadPool = new ThreadPoolExecutor(2, 3000, 3,  TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(5000),  new ThreadPoolExecutor.DiscardOldestPolicy());  for(int i=0;i<2000;i++){if(i<200){try {Random random = new Random();System.out.println(random.nextInt(100));Thread.sleep(random.nextInt(100));} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}threadPool.execute(new Runnable() {@Overridepublic void run() {// TODO Auto-generated method stubtry {//调用存储过程,对数据进行操作t.oper();} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}});}

  

因为是集群部署,所有将调用存储过程的方法设置为同步方法也不起作,最后想到了mysql的悲观锁,设置行级别的悲观锁,然后再获取锁的下一步进行数据判断,来进行处理

//加悲观锁的语句

SELECT usableSum INTO @usableSum FROM t_user WHERE id=in_uid FOR UPDATE;
SET @usableSum = IFNULL(@usableSum,0);
IF @usableSum <=0 THEN
ROLLBACK;
SET out_ret = -7;
SET out_desc = '余额不足';
LEAVE _return;
END IF;

IF @usableSum <in_money THEN
ROLLBACK;
SET out_ret = -8;
SET out_desc = 余额不足';
LEAVE _return;
END IF;

经过测试,完美的解决了数据同步的问题,

如果使用的Hibernate进行数据库操作,可以使用以下方式对数据库进行加锁

 String hqlStr ="from TUser as user where user.name='Erica'";Query query = session.createQuery(hqlStr);query.setLockMode("user",LockMode.UPGRADE); // 加锁
List userList = query.list();// 执行查询,获取数据

query.setLockMode 对查询语句中,特定别名所对应的记录进行加锁(我们为 TUser 类指定了一个别名 “user” ),这里也就是对返回的所有 user 记录进行加锁。

但是使用悲观锁对数据库的性能开销影响比较大,如果是大量的多线程并发的话,会造成数据库性能开销营销太大,这个时候推荐使用乐观锁来进行加锁,乐观锁相对于悲观锁采取了更加宽松的加锁机制,悲观锁属于排他的,当对数据进行加锁后,其他人无法获取此数据,只能当上个操作释放掉锁,悲观锁是利用字段来进行加锁的,可以在表中添加一个字段version,每次获取version,同时更新数据的时候,将此version进行+1操作,对version进行对比

转载于:https://www.cnblogs.com/muxiaozi/p/5035776.html

利用nginx集群式部署服务器中,数据同步问题相关推荐

  1. 解析Linux内核源码中数据同步问题丨C++后端开发丨Linux服务器开发丨Linux内核开发丨驱动开发丨嵌入式开发丨内核操作系统

    剖析Linux内核源码数据同步 1.pdflush机制原理 2.超级块同步/inode同步 3.拥塞及强制回写技术 视频讲解如下,点击观看: 解析Linux内核源码中数据同步问题丨C++后端开发丨Li ...

  2. Java利用Apace POI读取Excel中数据

    Java利用Apace POI读取Excel中数据,解析数据 @Testpublic void readExcel() throws IOException{FileSystemView fsv = ...

  3. 【Redis】Redis主从同步中数据同步原理

    [Redis]Redis主从同步中数据同步原理 文章目录 [Redis]Redis主从同步中数据同步原理 1. 全量同步 1.1 判断是否第一次数据同步 2. 增量同步 3. 优化Redis主从集群 ...

  4. Rsync服务配置详解,实现服务器间数据同步!

    1.1 什么是rsync? rsync是Unix下的一款应用软件,它能同步更新两处计算机的文件与目录,并适当利用差分编码以减少数据传输.rsync中一项与其他大部分类似程序或协议中所未见的重要特性是镜 ...

  5. MySQL数据库实现本地数据库和远程服务器数据库数据同步

    项目中有两个数据库:本地数据库和远程服务器数据库.数据要在本地经过数据洗涤后才传上服务器数据库.之前用的Navicat工具,但是速度慢,且无法设置定时同步.后来改用Datax,它的效率真的非常高. D ...

  6. 服务器otter部署-实现MySql数据同步

    资源下载 链接:https://pan.baidu.com/s/1P1nvfvkRSk_vZ4ulXbfTxg 提取码:rw55 Zookeeper 创建目录 新建data目录 解压并修改配置文件 进 ...

  7. 利用NGINX搭建部署直播流媒体服务器

    直播如今是一个老生常谈的问题,怎么用于直播,大多数人只晓得,大佬某平台直播软件,点击开始即可直播.那么如何来搭建一个简易的直播平台呢?仅仅是有直播功能,没有涉及转码以及播放软件. 安装nginx以及r ...

  8. mysql换服务器后数据同步_mysql配置主从,主服务器之前的数据可不可以同步过来...

    Slave_SQL_Running: No mysql同步故障解决 如果数据不同步可以尝试该资料 mysql> show slave status\G Slave_IO_Running: Yes ...

  9. linux搭建rtmp服务器搭建,linux下利用Nginx搭建RTMP服务器

    RTMP 实时消息传递协议(RTMP)由Macromedia开发,作为为其Flash技术传输数据,音频和视频的方法.Macromedia随后被Adobe收购,因为该规范已部分发布,使第三方能够在Ado ...

最新文章

  1. LeetCode题目:两数之和2
  2. Spring Boot 使用 Graylog 收集日志
  3. 一出好戏不止是部电影,它也正接近你的生活。
  4. 使用相对长度单位rem布局网页内容
  5. Java并发编程实战~Immutability模式
  6. Storm-源码分析-Topology Submit-Client
  7. 地老天荒只是一个华丽的传说
  8. 联想 R9000 系列以及Realtek Semiconductor Co., Ltd. Device 88xx系列 Ubuntu WIFI 不能使用
  9. 【Java 常用类】java.util包(5)Date类的常用方法
  10. 2525 小b的字符串(模拟)
  11. Excel查找快捷键:Ctrl+F
  12. python计算md5码
  13. SAP FICO 固定资产批导
  14. 台式计算机排行榜2018,CPU天梯图性能排行榜 台式电脑CPU天梯图2018年4月最新版...
  15. 字符自编车牌号c语言,自编车牌号技巧,自编车牌号码大全
  16. 图像跟踪(1) CSK
  17. 如何识别哭泣csdn_你上一次流泪是什么时候?| 研究:几乎不哭泣的4类人
  18. 常用的一些子域名,旁站查询
  19. 轻松实现离线地图-离线地图-地图瓦片下载
  20. 如何判断示波器输入信号超限

热门文章

  1. openssl 基本算法小例
  2. linux mod文件,mod文件扩展名,mod文件怎么打开?
  3. 360能卸载oracle,如何完全卸载Oracle
  4. 录音权限 推送_友邻正式推出Linux版本录音系统
  5. Maven常见警告解决办法
  6. 【Spring】Spring Security OAuth2 JWT 认证
  7. 【Elasticsearch】Elasticsearch自定义评分的N种方法
  8. 【clickhouse】clickhouse数据文件目录移动到新目录并建立软连接
  9. 【java】Java对象为啥要实现Serializable接口?
  10. 【Docker】Mac下Docker启动Kubernetes处于一直启动中(卡死)