日期:2014-05-16  浏览次数:20454 次

openfire(4)数据库浅析之序列

openfire中提供了生产序列的管理器(SequenceManager),其构造函数如下:

?

public SequenceManager(int seqType, int size) {
??????? managers.put(seqType, this);
??????? this.type = seqType;
??????? this.blockSize = size;
??????? currentID = 0l;
??????? maxID = 0l;
??? }

seqType,为序列类型,默认有3种类型:

??? public static final int ROSTER = 18;
??? public static final int OFFLINE = 19;
??? public static final int MUC_ROOM = 23;

?

size:序列的增加值。例如a=a+2;

?

?

private void getNextBlock(int count) {
??????? if (count == 0) {
??????????? Log.error("Failed at last attempt to obtain an ID, aborting...");
??????????? return;
??????? }

??????? Connection con = null;
??????? PreparedStatement pstmt = null;
??????? ResultSet rs = null;
??????? boolean abortTransaction = false;
??????? boolean success = false;

??????? try {
??????????? con = DbConnectionManager.getTransactionConnection();
??????????? // Get the current ID from the database.
??????????? pstmt = con.prepareStatement(LOAD_ID);
??????????? pstmt.setInt(1, type);
??????????? rs = pstmt.executeQuery();

??????????? long currentID = 1;
??????????? if (rs.next()) {
??????????????? currentID = rs.getLong(1);
??????????? }
??????????? else {
??????????????? createNewID(con, type);
??????????? }
??????????? DbConnectionManager.fastcloseStmt(rs, pstmt);

??????????? // Increment the id to define our block.
??????????? long newID = currentID + blockSize;
??????????? // 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 (SQLException e) {
??????????? Log.error(e.getMessage(), e);
??????????? abortTransaction = true;
??????? }
??????? finally {
??????????? DbConnectionManager.closeStatement(rs, pstmt);
??????????? DbConnectionManager.closeTransactionConnection(con, abortTransaction);
??????? }

??????? if (!success) {
??????????? Log.error("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.sleep(75);
??????????? }
??????????? catch (InterruptedException ie) {
??????????????? // Ignore.
??????????? }
??????????? getNextBlock(count - 1);
??????? }
??? }

此方法为:更具类型到数据库中ofid查询ID,获取表中的id,然后id加一个变量,然后将新的id更新到数据库中。

?

private void createNewID(Connection con, int type) throws SQLException {
??????? Log.warn("Autocreating jiveID row for type '" + type + "'");

??????? // create new ID row
??????? PreparedStatement pstmt = null;

??????? try {
??????????? pstmt = con.prepareStatement(CREATE_ID);
??????????? pstmt.setInt(1, type);
??????????? pstmt.execute();
??????? }
??????? finally {
??????????? DbConnectionManager.closeStatement(pstmt);
??????? }
??? }

在表中创建一条序列的记录。

?

此篇文章就到此,稍后会有更多关于openfire的个人解读。

联系方式(qq):851392159

出处: