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. ...
随机推荐
- ios jsbrige
<!doctype html> <html> <head> <meta charset="utf-8"> <title> ...
- OAuth认证的过程
在认证和授权的过程中涉及的三方包括: 服务提供方,用户使用服务提供方来存储受保护的资源,如照片,视频,联系人列表. 用户,存放在服务提供方的受保护的资源的拥有者. 客户端,要访 ...
- 面向对象程序设计-C++_课时21引用
数据类型 & 别名=对象名; #include <iostream> using namespace std; int * f(int * x) { (*x)++; return ...
- 使用sphinx索引mysql数据
数据库表如下 mysql> select * from tb_account; +----+-------+------+ | id | name | age | +----+-------+- ...
- UI_拖动View
方法一 在touchesMoved中 // 获取到触摸的手指 UITouch *touch = [touches anyObject]; // 获取集合中对象 // 获取開始时的触摸点 CGPoint ...
- 君子性非异也,善假于物也 - Threejs 引入TrackballControls 查看场景
君子性非异也,善假于物也 - Threejs 引入TrackballControls 查看场景 太阳火神的漂亮人生 (http://blog.csdn.net/opengl_es) 本文遵循" ...
- 潜在语义分析Latent semantic analysis note(LSA)原理及代码
文章引用:http://blog.sina.com.cn/s/blog_62a9902f0101cjl3.html Latent Semantic Analysis (LSA)也被称为Latent S ...
- 2014.8.30.ref,out,params,enum,递归
(一)ref 函数形参变量的输入有两种方式:传值,传址.而ref则为传址.eg: static int Add(ref int n) { Console.WriteLine("Add---- ...
- ##DAY11 UITableView编辑
##DAY11 UITableView编辑 每一个视图控制器都有一个编辑按钮,因为项目中编辑的应用场景非常多,所以系统预留了一个编辑按钮供我们使用 self.navigationItem.leftBa ...
- oracle 与sql server 部分内置函数替换
1,trunc--convert oracle: select trunc(sysdate) from dual 输出:2016/5/24 sql server:select CONVERT(va ...