📄 tableid.java
字号:
package com.laoer.bbscs.util;
import java.sql.*;
import com.laoer.bbscs.db.*;
/**
* <p>Title: ��������V5.0</p>
* <p>Description: BBS-CS��������V5.0</p>
* <p>Copyright: Copyright (c) 2003</p>
* <p>Company: laoer.com</p>
* @author ������
* @version 5.0
*/
public class TableID {
private static final String LOAD_ID =
"SELECT IDValue FROM tableid WHERE ID =?";
private static final String UPDATE_ID =
"UPDATE tableid SET IDValue=? WHERE ID=? AND IDValue=?";
/**
* The number of ID's to checkout at a time. 15 should provide a good
* balance between speed and not wasing too many ID's on appserver restarts.
* Feel free to change this number if you believe your Jive setup warrants
* it.
*/
private static final int INCREMENT = 15;
// Statically startup a sequence manager for each of the five sequence
// counters.
private static TableID[] managers;
static {
managers = new TableID[6];
for (int i = 0; i < managers.length; i++) {
managers[i] = new TableID(i);
}
}
/**
* Returns the next ID of the specified type.
*
* @param type the type of unique ID.
* @return the next unique ID of the specified type.
*/
public static long nextID(int type) {
return managers[type].nextUniqueID();
}
public static long nextID() {
return managers[0].nextUniqueID();
}
private int type;
private long currentID;
private long maxID;
/**
* Creates a new DbSequenceManager.
*/
public TableID(int type) {
this.type = type;
currentID = 0l;
maxID = 0l;
}
/**
* Returns the next available unique ID. Essentially this provides for the
* functionality of an auto-increment database field.
*/
public synchronized long nextUniqueID() {
if (! (currentID < maxID)) {
// Get next block -- make 5 attempts at maximum.
getNextBlock(5);
}
long id = currentID;
currentID++;
return id;
}
/**
* Performs a lookup to get the next availabe ID block. The algorithm is as
* follows:<ol>
* <li> Select currentID from appropriate db row.
* <li> Increment id returned from db.
* <li> Update db row with new id where id=old_id.
* <li> If update fails another process checked out the block first; go
* back to step 1. Otherwise, done.
* </ol>
*/
private void getNextBlock(int count) {
if (count == 0) {
System.err.println("Failed at last attempt to obtain an ID, aborting...");
return;
}
boolean success = false;
TranContext DBSQL = new TranContext();
Connection con = null;
PreparedStatement pstmt = null;
try {
con = DBSQL.getCon();
// Get the current ID from the database.
pstmt = con.prepareStatement(LOAD_ID);
pstmt.setInt(1, type);
ResultSet rs = pstmt.executeQuery();
if (!rs.next()) {
throw new SQLException("Loading the current ID failed. The " +
"jiveID table may not be correctly populated.");
}
long currentID = rs.getLong(1);
pstmt.close();
// Increment the id to define our block.
long newID = currentID + INCREMENT;
// The WHERE clause includes the last value of the id. This ensures
// that an update will occur only if nobody else has performed an
// update first.
pstmt = con.prepareStatement(UPDATE_ID);
pstmt.setLong(1, newID);
pstmt.setInt(2, type);
pstmt.setLong(3, currentID);
// Check to see if the row was affected. If not, some other process
// already changed the original id that we read. Therefore, this
// round failed and we'll have to try again.
success = pstmt.executeUpdate() == 1;
if (success) {
this.currentID = currentID;
this.maxID = newID;
}
}
catch (Exception sqle) {
sqle.printStackTrace();
}
finally {
try {
pstmt.close();
}
catch (Exception e) {
e.printStackTrace();
}
try {
con.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
if (!success) {
System.err.println("WARNING: failed to obtain next ID block due to " +
"thread contention. Trying again...");
// Call this method again, but sleep briefly to try to avoid thread
// contention.
try {
Thread.currentThread().sleep(75);
}
catch (InterruptedException ie) {}
getNextBlock(count - 1);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -