mysql 数据丢失更新的解决方法

最新看《innodb 引擎内幕》,作者有介绍丢失更新的问题,这里记录自己的想法和方案

-------------------------------------------------------------------

问题描述:

 mysql 数据库丢失更新的定义:(其实在数据库角度都不会产生丢失更新的问题,问题的源头应用程序逻辑更新的问题)

  1. 事务1 查询一行数据放在本地缓存,并且显示给用户user1        -->select balance from account where user= ‘a‘ ;

  2. 事务2 查询同样的一行数据放在本地缓存,并且显示给用户user2    -->select balance from account where user= ‘a‘ ;

  3. 用户user1修改这条数据,并且更新提交数据库     --> update account set balance = balance -100 where user= ‘a‘ ;

  4. 用户user2修改显示的数据,并且更新提交数据库  --> update account set balance = balance -800 where user= ‘a‘ ;

显然上面user1 更新的数据丢失了,这也是更新覆盖,比如用户转账的操作。a 账户总共1000,事务1和事务2查询账户都是1000,然后事务1账户扣减100,提交。事务2扣减800提交。这时候账户余额为200,事务1扣减的100 会不翼而飞,这会导致严重的问题。

-------------------------------------------------------------------

暂时想到两种解决办法:

解决办法1:使用悲观锁

  1)使用顺序 --> select balance from account where user= ‘a‘  for update

  2)更新 --> update account set balance = balance -100 where user= ‘a‘     

解决办法2: 使用乐观锁

  1)表增加字段 jpa_version int 版本号  -->  select balance,version from account where user= ‘a‘

  2) 更新 --> update account set balance = balance -100 where user= ‘a‘ and jpa_version = ${version}             

总结:

  对于账户交易建议直接使用悲观,数据库的性能很高,并发度不是很高的场景两者性能没有太大差别。如果是交易减库存的操作可以考虑乐观锁,保证并发度。

原文地址:https://www.cnblogs.com/immer/p/10930020.html

时间: 2024-10-26 20:15:00

mysql 数据丢失更新的解决方法的相关文章

Java TM 已被阻止,因为它已过时需要更新的解决方法

公司的堡垒机需要通过浏览器登陆,且该堡垒机的网站需要Java的支持,最近通过浏览器登陆之后总是提示"java TM 已被阻止,因为它已过时需要更新的解决方法"导致登陆之后不能操作, 但是操作系统中确实已经安装了比较新的JDK,安装的JDK版本是jdk-7u67-windows-i586,因为太烦人,所以决定搞清楚报错的原因,一劳永逸,彻底解决这个问题 准备工作:安装JDK,安装版本jdk-7u67-windows-i586.exe,因为机器的Eclipse还依赖64位的JDK,所以另安

今天用pro安装nginx+php+mysql出现问题的解决方法

今天用pro安装nginx+php+mysql出现问题的解决方法 by 伍雪颖 dyld: Library not loaded: @@[email protected]@/openssl/1.0.1h/lib/libcrypto.1.0.0.dylib Referenced from: /usr/local/opt/openssl/lib/libssl.1.0.0.dylib Reason: image not found 解决方法:重装openssl Starting MySQL . ERR

错误:“Cannot load JDBC driver class 'com.mysql.jdbc.Driver”的解决方法

"Cannot load JDBC driver class 'com.mysql.jdbc.Driver " 表示没有JDBC连接MySql的驱动包,因此需要手动添加驱动包到WEB-INF目录下的lib目录中. 解决方法: 从网上下载mysql-connector-java.jar,将其放到"D:\workspace\my-web\src\main\webapp\WEB-INF\lib"目录下,即可解决上述问题. 错误:"Cannot load JDBC

Android SDK无法显示更新列表解决方法

解决办法: 第一步: 打开Windows中C:\WINDOWS\system32\drivers\etc\hosts,然后添加以下内容: 203.208.46.146 dl.google.com 203.208.46.146 dl-ssl.google.com 74.125.113.121 developer.android.com 第二步: 打开Android SDK Manager,选上方的菜单Tools,进入Options,在"Force https://- "前面打钩,就可以更

mysql error nr.1045 解决方法

源地址:http://yanshuaijun.2010.blog.163.com/blog/static/362411622011102443056225/ 主题:mysql error nr.1045 解决方法 2011-11-24 16:30:56|  分类: mysql|举报|字号 订阅 1.进入cmd手动停止mysql服务:net stop mysql. 2.修改C:\Program Files\MySQL\MySQL Server 5.1\ 目录下的my.ini文件,在[mysqld]

c#写入Mysql中文显示乱码 解决方法 z

mysql字符集utf8,c#写入中文后,全部显示成?,一个汉字对应一个? 解决方法:在数据库连接字符串中增加字符集的说明,Charset=utf8,如 MySQLConnection con = new MySQLConnection("server=127.0.0.1;uid=root;pwd=;database=test;Charset=utf8"); 搞定 c#写入Mysql中文显示乱码 解决方法 z,布布扣,bubuko.com

UCenter info: MySQL Query Error的解决方法----For Discuz!

备注: 出现这个问题同时会造成论坛注册,登录和发帖时等页面无法跳转(APP1运行不正常) 案例: UCenter info: MySQL Query Error SQL:SELECT * FROM [Table]notelist WHEREclosed='0' AND app1<'1' AND app1>'-5' LIMIT 1 Error:Unknown column 'app1' in 'whereclause' Errno:1054 分析: 错误是说在UCenter数据库的notelis

mysql日常错误信息解决方法:InnoDB: and force InnoDB to continue crash recovery here.

今天早上上班来打开环境,mysql报了这个错误,猜到的原因应该是昨天晚上下班没等mysql服务器退出就关闭计算机. ? 1 2 3 4 5 6 7 8 9 10 11 12 13 2014-05-09 09:44:25 4128 [ERROR] InnoDB: Attempted to open a previously opened tablespace. Previous tablespace manage_yunfan/nav_areasource uses space ID: 2 at

windows下忘记mysql root密码的解决方法(转)

windows下忘记mysql root密码的解决方法(转) 分类: 数据库 mysql5.5安装目录为 e:\mysql5.5 问题:开发机器上的mysql root 密码忘记鸟! 通过一番搜索,解决问题步骤下: 1.dos命令行窗口 进入e:\mysql5.5\bin ,停止mysql 服务 e:\mysql5.5\bin>net stop mysql 注意:看看那任务管理器中是否有mysqld.exe进程,如有,kill them all. 2. 以不检查权限的方式启动mysql e:\m