From: http://xm-koma.iteye.com/blog/1961793
In the project application, there was the following scenario:
An int-type pipeline number is required to be sent in the interface. Because of the multithreaded mode, there may be duplication if timestamp is used (of course, the probability is very small).
So I think of using an independent self-increasing sequence to solve this problem.
The current database is: mysql
Because mysql and oracle are different and do not support direct sequence, we need to create a table to simulate the function of sequence for the following reasons:
Step 1: Create -- Sequence Management Table
- DROP TABLE IF EXISTS sequence;
- CREATE TABLE sequence (
- name VARCHAR(50) NOT NULL,
- current_value INT NOT NULL,
- increment INT NOT NULL DEFAULT 1,
- PRIMARY KEY (name)
- ) ENGINE=InnoDB;
Step 2: Create a function that takes the current value
- DROP FUNCTION IF EXISTS currval;
- DELIMITER $
- CREATE FUNCTION currval (seq_name VARCHAR(50))
- RETURNS INTEGER
- LANGUAGE SQL
- DETERMINISTIC
- CONTAINS SQL
- SQL SECURITY DEFINER
- COMMENT ''
- BEGIN
- DECLARE value INTEGER;
- SET value = 0;
- SELECT current_value INTO value
- FROM sequence
- WHERE name = seq_name;
- RETURN value;
- END
- $
- DELIMITER ;
Step 3: Create a function that takes the next value
- DROP FUNCTION IF EXISTS nextval;
- DELIMITER $
- CREATE FUNCTION nextval (seq_name VARCHAR(50))
- RETURNS INTEGER
- LANGUAGE SQL
- DETERMINISTIC
- CONTAINS SQL
- SQL SECURITY DEFINER
- COMMENT ''
- BEGIN
- UPDATE sequence
- SET current_value = current_value + increment
- WHERE name = seq_name;
- RETURN currval(seq_name);
- END
- $
- DELIMITER ;
Step 4: Create -- update the function of the current value
- DROP FUNCTION IF EXISTS setval;
- DELIMITER $
- CREATE FUNCTION setval (seq_name VARCHAR(50), value INTEGER)
- RETURNS INTEGER
- LANGUAGE SQL
- DETERMINISTIC
- CONTAINS SQL
- SQL SECURITY DEFINER
- COMMENT ''
- BEGIN
- UPDATE sequence
- SET current_value = value
- WHERE name = seq_name;
- RETURN currval(seq_name);
- END
- $
- DELIMITER ;
Step 5: Testing function functions
When the above four steps are completed, you can use the following data to set the sequence name to be created, as well as to set the initial value and get the current value and the next value.
INSERT INTO sequence VALUES ('TestSeq', 0, 1); - - Add a sequence name and initial value, and self-increment
SELECT SETVAL('TestSeq', 10); - - Sets the initial value of the specified sequence
SELECT CURRVAL('TestSeq'); queries the current value of the specified sequence
SELECT NEXTVAL('TestSeq'); -- Query for the next value of the specified sequence
In java code, sql statements can be created directly to query the next value, which solves the unique problem of pipeline number.
Post out some code (tested)
- public void testGetSequence() {
- Connection conn = JDBCUtils.getConnection(url, userName, password);
- String sql = "SELECT CURRVAL('TestSeq');";
- PreparedStatement ptmt = null;
- ResultSet rs = null;
- try {
- ptmt = conn.prepareStatement(sql);
- rs = ptmt.executeQuery();
- int count = 0;
- while (rs.next()) {
- count = rs.getInt(1);
- }
- System.out.println(count);
- } catch (SQLException e) {
- e.printStackTrace();
- } finally {
- JDBCUtils.close(rs, ptmt, conn);
- }
- }
ps: In the application, there is also a way to simulate self-increasing sequence with Java code. The idea is to create a table to store sequence, and then use java to call sql statements to query and modify the value of the specified sequence name in the table. This way, Please add synchronized. Specific code is not uploaded here, because the implementation has not been tested.