Java如何实现对Mysql数据库的行锁
<!-- (事务管理)transaction manager, use JtaTransactionManager for global tx -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- 使用annotation定义事务 -->
<tx:annotation-driven transaction-manager="transactionManager" />
在指定代码处添加事务注解
@Transactional
@Override
public boolean increaseBalanceByLock(Long userId, BigDecimal amount)
throws ValidateException {
long time = System.currentTimeMillis();
//获取对记录的锁定
UserBalance balance = userBalanceDao.getLock(userId);
LOGGER.info("[lock] start. time: {}", time);
if (null == balance) {
throw new ValidateException(
ValidateErrorCode.ERRORCODE_BALANCE_NOTEXIST,
"user balance is not exist");
}
boolean result = userBalanceDao.increaseBalanceByLock(balance, amount);
long timeEnd = System.currentTimeMillis();
LOGGER.info("[lock] end. time: {}", timeEnd);
return result;
}
通过db的悲观锁,实际测试该方法确实可以有效控制,不过在大并发量的情况下,可能会有性能问题
<select id="getLock" resultMap="BaseResultMap" parameterType="java.lang.Long">
<![CDATA[
select * from user_balance where id=#{id,jdbcType=BIGINT} for update;
]]>
</select>
update user_balance set Balance = #{balance,jdbcType=DECIMAL},Version = Version+1 where Id = #{id,jdbcType=BIGINT} and Version = #{version,jdbcType=BIGINT}
这是一种不使用数据库锁的方法,解决方式也很巧妙。当然,在大量并发的情况下,一次扣款需要重复多次的操作才能成功,还是有不足之处的。
延伸:
乐观锁:对每次的数据操作都保持乐观的态度,因此不对数据进行上锁。那么就存在数据会被反复读写的情况,所以每次修改数据的时候需要对数据进行判断是否被修改过。
悲观锁:对每次的数据操作持悲观态度,操作时上锁,防止操作时数据被他人修改
使用场景:
乐观锁:由于不上锁,性能较好,适用于读大于写的情况,如果写较多,则会导致重复尝试写入均失败。
悲观锁:上锁,数据写入时会导致读被挂起,适合写大于读的场景
实现:
乐观锁:在db中,可以增加版本号控制,java中的CAS等
悲观锁:db的for update,java中的synchronize等
Java如何实现对Mysql数据库的行锁的更多相关文章
- 实现对MySQL数据库进行分库/分表备份(shell脚本)
工作中,往往数据库备份是件非常重要的事情,毕竟数据就是金钱,就是生命!废话不多,下面介绍一下:如何实现对MySQL数据库进行分库备份(shell脚本) Mysq数据库dump备份/还原语法: mysq ...
- java(2014)实现对mysql数据库分页的代码
package util; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultS ...
- C++实现对MySQL数据库的连接,以及增删改查
安装好MySQL,建好数据表的前提下. 如果只是想简单实现添加数据或者其他一个操作数据,可以参考另一篇博客. https://www.cnblogs.com/ming-4/p/11544514.htm ...
- 利用shell脚本实现对mysql数据库的备份
#!/bin/bash #保存备份个数 number=3 #备份保存路径 backup_dir=/root/mysqlbackup #日期 dd=`date +%Y%m%d` #备份工具 tool=m ...
- c++简单实现对mysql数据库操作
1.连接数据库 #include <mysql.h> #include <iostream> #include<string> #include<vector ...
- 用shell 实现对MySQL数据库分页
参考链接 http://mp.weixin.qq.com/s?__biz=MzAxMzE4MDI0NQ==&mid=208299533&idx=1&sn=4cab00793eb ...
- Java Web学习系列——Maven Web项目中集成使用Spring、MyBatis实现对MySQL的数据访问
本篇内容还是建立在上一篇Java Web学习系列——Maven Web项目中集成使用Spring基础之上,对之前的Maven Web项目进行升级改造,实现对MySQL的数据访问. 添加依赖Jar包 这 ...
- ava基础MySQL存储过程 Java基础 JDBC连接MySQL数据库
1.MySQL存储过程 1.1.什么是存储过程 带有逻辑的sql语句:带有流程控制语句(if while)等等 的sql语句 1.2.存储过程的特点 1)执行效率非常快,存储过程是数据库的服 ...
- 【mysql】备份篇2:使用java程序定期备份mysql数据库
承接备份篇1, 在备份篇1中,使用dat文件加+系统计划任务程序完成mysql定期备份任务 在这一篇,备份使用java程序定期备份mysql数据库. 下面代码和程序思想给出: package com. ...
随机推荐
- 微软Windows 7 “可启动U盘”制作工具及使用方法,非常的简单
目前,用“可启动U盘”替代光驱光盘安装操作系统,已经成为一种时尚(至少对没有刻录机或不愿购买光碟的群体是这样).制作“可启动U盘”的方法和工具很多,区别无非是制作的难易程度和对“U盘类型”的支持程度. ...
- QDialog弹出一个窗口,改变窗口大小
创建一个QT应用 文件->新建文件或项目 Application->Qt Widgets Application 其他下一步 基类选择QDialog 其他下一步 resize() 改变窗口 ...
- select option 下拉多选单选bootstrap插件使用总结
<select id="example-getting-started" multiple="multiple"> <option value ...
- BFC / hasLayout
BFC - block formatting context 1.float的值不能为none 2.overflow的值不能为visible 3.display的值为table-cell,table- ...
- 性能优化工具---sar
简介: System Activity Reporter系统活动情况报告 下载地址: http://pagesperso-orange.fr/sebastien.godard/download.htm ...
- React.js 是什么?
在相当长的一段时间内,我很努力地去尝试理解 React 是什么以及它在应用架构上的健壮程度.这篇文章解答了我希望别人为我解答的疑惑. React 是什么? 和 Angular,Ember,Backbo ...
- Ubuntu - Dconf 注册表键值修改参考表
gsettings reset org.gnome.desktop.wm.preferences theme默认gnomegsettings set org.gnome.desktop.interfa ...
- 关于重复记录和外部 ID (CRM导入提示已找到重复的查找引用)
http://docs.huihoo.com/oracle/crm-on-demand/21/local/html/Release21_SimpleChinese/index.htm?toc.htm? ...
- Log4net 自定义字段到数据库(二)
这种方法比第一种方法麻烦些 Log4Net.config <?xml version="1.0" encoding="utf-8" ?> <c ...
- JS兼容性问题列表
记录平时遇见的兼容性问题,有更好的解决办法希望各位提出,会随着开发遇到问题而更新,标记为黄色的为未解决和猜测答案 提出时间 问题描述 解决方案 2014/10/22 submit按钮阻止了默认事件不能 ...