【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这个 ...
随机推荐
- paper 90:人脸检测研究2015最新进展
搜集整理了2004~2015性能最好的人脸检测的部分资料,欢迎交流和补充相关资料. 1:人脸检测性能 1.1 人脸检测测评 目前有两个比较大的人脸测评网站: 1:Face Detection Data ...
- HttpUtility.HtmlEncode 方法
將字串轉換為 HTML 編碼的字串. 例如: publicstringWelcome(string name,int numTimes =1){ returnHttpUtility.HtmlE ...
- 广播发送者&广播接收者介绍
1.广播接收者 广播接收者简单地说就是接收广播意图的Java类,此Java类继承BroadcastReceiver类,重写: public void onReceive(Context context ...
- Windows下USB磁盘开发系列三:枚举系统中U盘、并获取其设备信息
前面我们介绍了枚举系统中的U盘盘符(见<Windows下USB磁盘开发系列一:枚举系统中U盘的盘符>).以及获取USB设备的信息(见<Windows下USB磁盘开发系列二:枚举系统中 ...
- mysql的内存表和临时表
内存表: session $ mysql -uroot root@(none) ::>use test Database changed root::>CREATE TABLE tmp_m ...
- jeditable参数详解
一.导入js文件 <script type="text/javascript" src="jquery-1.10.2.min.js"></sc ...
- oracle 自动关闭 数据库连接
数据库启动后过一会自动断开连接(大概10分钟) 方法一.直接修改资源配置文件 分三个步骤在sqlplus环境下完成. 第一步,查询资源文件,找到CONNECT_TIME所在的pr ...
- Oracle集合运算符 交集 并集 差集
集合运算符:UNION/UNION ALL 并集,INTERSECT 交集,MINUS 差集 一.union求并集,公共部分只有包含一次 例:求emp表ename中含’A‘或含有‘M’ SQL&g ...
- nohup DEMO
nohup,顾名思义:挂起免疫. nohup命令可以防止当你退出系统时,在后台运行的进程被终止.它能让你运行的命令或脚本在你退出系统后继续在后台运行. nohup命令不能自动的将任务放在后台运行,所以 ...
- 11、Jsp加强/EL表达式/jsp标签
1 Jsp基础回顾 Jsp基础 1)Jsp的执行过程 tomcat服务器完成:jsp文件->翻译成java文件->编译成class字节码文件-> 构造类对象-> 调用方法 to ...