【MySQL】MySQL的Sequence
Oracle的Sequence用爽了,发现MySQL没有Sequence,那么,自己写一个呗。
> 最简单的实现
先建一个表存储当前值:
CREATE TABLE `t_sequence` (
`sequence_name` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '序列名称' ,
`value` int(11) NULL DEFAULT NULL COMMENT '当前值' ,
PRIMARY KEY (`sequence_name`)
)
ENGINE=InnoDB
DEFAULT CHARACTER SET=utf8 COLLATE=utf8_general_ci
ROW_FORMAT=COMPACT
;
获取当前值的函数:
CREATE DEFINER = `root`@`localhost` FUNCTION `currval`(sequence_name varchar(64))
RETURNS int(11)
BEGIN
declare current integer;
set current = 0;
select t.value into current from t_sequence t where t.sequence_name = sequence_name;
return current;
end;
获取下一个值:
CREATE DEFINER = `root`@`localhost` FUNCTION `nextval`(sequence_name varchar(64))
RETURNS int(11)
BEGIN
declare current integer;
set current = 0; update t_sequence t set t.value = t.value + 1 where t.sequence_name = sequence_name;
select t.value into current from t_sequence t where t.sequence_name = sequence_name; return current;
end;
写一个多线程程序测试下并发:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; public class JDBCTools { public static void main(String[] args) throws Exception {
JDBCTools.execute("update t_balance t set t.balance = 300 where t.user_id = 2");
JDBCTools.query("select * from t_balance t");
} public static String HOST = "localhost";
public static String PORT = "3306";
public static String DATABASE_NAME = "demo";
public static String USER_NAME = "root";
public static String PASSWORD = "123456"; /**
* 获取数据库连接
* @return 数据库连接
*/
public static Connection getConn() throws Exception {
Class.forName("com.mysql.jdbc.Driver"); String url = "jdbc:mysql://" + HOST + ":" + PORT + "/" + DATABASE_NAME + "?user=" + USER_NAME + "&password=" + PASSWORD + "&useUnicode=true&characterEncoding=UTF8";
Connection connection = DriverManager.getConnection(url);
return connection;
} /**
* 关闭资源
*/
public static void closeResource(Connection conn, Statement st, ResultSet rs) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
// TODO 处理异常
e.printStackTrace();
}
}
if (st != null) {
try {
st.close();
} catch (SQLException e) {
// TODO 处理异常
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
// TODO 处理异常
e.printStackTrace();
}
}
} /**
* 查询SQL
* @param sql 查询语句
* @return 数据集合
* @throws SQLException
*/
public static List<Map<String, String>> query(String sql) throws Exception {
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
List<Map<String, String>> resultList = null; try {
connection = JDBCTools.getConn(); statement = connection.createStatement();
resultSet = statement.executeQuery(sql); ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
int columnCount = resultSetMetaData.getColumnCount();
String[] columnNames = new String[columnCount + 1];
for (int i = 1; i <= columnCount; i++) {
columnNames[i] = resultSetMetaData.getColumnName(i);
} resultList = new ArrayList<Map<String, String>>();
Map<String, String> resultMap = new HashMap<String, String>();
resultSet.beforeFirst();
while (resultSet.next()) {
for (int i = 1; i <= columnCount; i++) {
resultMap.put(columnNames[i], resultSet.getString(i));
}
resultList.add(resultMap);
}
// System.out.println("成功查询数据库,查得数据:" + resultList);
} catch(Throwable t) {
// TODO 处理异常
t.printStackTrace();
} finally {
JDBCTools.closeResource(connection, statement, resultSet);
} return resultList;
} /**
* 执行SQL
* @param sql 执行的SQL
* @return 操作条数
*/
public static int execute(String sql) throws Exception {
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
int num = 0; try {
connection = JDBCTools.getConn(); statement = connection.createStatement();
num = statement.executeUpdate(sql); } catch(Throwable t) {
// TODO 处理异常
t.printStackTrace();
} finally {
JDBCTools.closeResource(connection, statement, resultSet);
} return num;
} }
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; public class Call { public static ConcurrentHashMap<String, String> map = new ConcurrentHashMap<String, String>(); public static void main(String[] args) {
ExecutorService es = Executors.newCachedThreadPool(); for (int i = 0; i < 100; i++) {
es.execute(new Runnable() { @Override
public void run() {
String key = getSequence();
if (!map.contains(key)) {
System.out.println("put " + key);
map.put(key, key);
} else {
System.out.println(key + " is exists.");
}
}
});
} } public static String getSequence() {
List<Map<String, String>> list = null;
try {
list = JDBCTools.query("select nextval('user_code') as current");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String temp = list.get(0).get("current");
return temp;
} }
> 用排他锁的方式
上面的程序虽然测试并无发现问题(有可能测试程序写得不好),理论上高并发会出现重复值,用排他锁重写了一下,不过效率会比较低:
CREATE DEFINER = `root`@`localhost` FUNCTION `nextval_safe`(sequence_name varchar(64))
RETURNS int(11)
BEGIN
declare current integer;
set current = 0; select t.value into current from t_sequence t where t.sequence_name = sequence_name for update;
update t_sequence t set t.value = t.value + 1 where t.sequence_name = sequence_name;
set current = current + 1; return current;
end;
【MySQL】MySQL的Sequence的更多相关文章
- 【转】MySQL中增加sequence管理功能(模拟创建sequence)
1.oracel可以直接支持sequence,但是mysql不支持sequence,因此我们要通过模拟sequence的方法在mysql中创建sequence.模拟sequence的方法:项目场景:项 ...
- MySQL :: MySQL 8.0 Reference Manual :: B.6.4.3 Problems with NULL Values https://dev.mysql.com/doc/refman/8.0/en/problems-with-null.html
MySQL :: MySQL 8.0 Reference Manual :: B.6.4.3 Problems with NULL Values https://dev.mysql.com/doc/r ...
- ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)
有时候,当我们使用"mysql"."mysqladmin"."mysqldump"等命令管理数据库时,服务器抛出类似如下错误: 一.错误现场 ...
- ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)
从供应商手中接手一个云平台(Windwos Azure)上的MySQL数据库,登录数据库时遇到错误: $mysql -uroot -p Enter password: ERROR 2002 (HY00 ...
- mac ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib /mysql/mysql.sock' (111)
之前装了mysql,今天打开mysql的时候报了个Can't connect to local MySQL server through socket '/var/lib /mysql/mysql.s ...
- 更换mysql数据目录后出现ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2) 的解决办法
服务器上的mysql默认数据目录为/var/lib/mysql/,同时服务器的/空间不是很大,而近期又有大量的日志需要导入进行分析,时常搞得/的空间捉襟见肘,晚上一狠心就想把mysql的数据目录转移到 ...
- 启动mysql错误ERROR 2002 (HY000): Can’t connect to local MySQL server through socket ‘/var/lib/mysql/mysql.sock’ (2)
ERROR 2002 (HY000): Can’t connect to local MySQL server through socket ‘/var/lib/mysql/mysql.sock’ ( ...
- ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)--MySQL错误
MySQL错误整理: 错误一: ERROR (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/my ...
- Can’t connect to local MySQL server through socket ‘/var/lib/mysql/mysql.sock’解决方法 + Linux启动/停止/重启Mysql数据库的方法
启动mysql 报错: ERROR 2002 (HY000): Can’t connect to local MySQL server through socket ‘/var/lib/mysql/m ...
- Can 't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock '(2) ;
Can 't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock '(2) ; 如果你在网上search这个 ...
随机推荐
- CSS_03_01_CSS类选择器
第01步:编写css样式:class_01.css @charset "utf-8"; /* CSS Document */ div.class01{ background-col ...
- datagridview 用法
标签:c# datagridview 用法 拖一个datagridview控件 初始的名字叫dataGridView1 准备工作: 点击控件右上角的三角,选择“添加列”添加表头的项 基本操作: ...
- mysql server安装及密码重置
官网上能下载到的mysql安装分两种:msi和zip安装 msi安装比较简单,直接下一步. 主要说zip格式的安装: 1.解压. zip解压后的文件夹改名后(也可以不改名)放在喜欢的位置.例如我放在C ...
- 夺命雷公狗---DEDECMS----33dedecms自定义搜索以及分页功能完成
我们现在要开始实现模版里面的搜索功能了,我们先找要做出一个检索提交表单,如下所示: 只要我们点击生成之后我们的表单就获取到了,可以直接拿生成好的html表单拿来用来测试下.. 将他嵌入首页的模版文件, ...
- 白盒测试的学习之路----(五)TestNG的参数分离
之前的测试用例直接嵌套在代码中,不便于维护和测试设计,应该单独把测试用例放在excel内,然后程序从中读取数据到相应的接口内即可.使用ava程序对Microsoft Office格式档案读和写的功能提 ...
- zw版【转发·台湾nvp系列Delphi例程】HALCON TileChannels
zw版[转发·台湾nvp系列Delphi例程]HALCON TileChannels unit Unit1;interfaceuses Windows, Messages, SysUtils, Var ...
- 安装VirtalBox虚拟机的一些问题归纳
1.分别下载VirtalBox软件和镜像,进行安装出现一个问题:换了一个.dll动态库,用管理员权限运行修改BIOS 中Intel Virtual Technology Enabled!2.功能:虚拟 ...
- yii2.0分页
本实例是对商品列表进行分页 1.Controller中,商品列表的方法actionList 引用分页类 actionList中: $goods_info=Goods::find()->joinW ...
- Google 开发新的开源系统 Fuchsia
google 最新os 下载 https://github.com/fuchsia-mirror/magenta 本文转自:http://www.oschina.net/news/76094/goog ...
- jenkins+jmeter+ant搭建接口测试平台
接口测试的重点是检查数据的交换,传递和控制管理过程以及系统间的相互逻辑依赖关系. 接口测试的流程 项目启动后,测试人员要尽早拿到接口测试文档. 开始编写接口测试用例 将接口测试用例部署到持续集成的测试 ...