All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sharksharding.util.sequence.mysql.CreateMysqlSequenceId Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2015-2101 gaoxianglong
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.sharksharding.util.sequence.mysql;

import java.sql.SQLException;
import java.util.concurrent.ConcurrentHashMap;
import com.sharksharding.exception.SequenceIdException;
import com.sharksharding.util.sequence.CreateSequenceIdServiceImpl;

/**
 * 生成基于Mysql的SequenceId
 * 
 * @author JohnGao
 * 
 * @version 1.3.5
 */
public class CreateMysqlSequenceId extends CreateSequenceIdServiceImpl {
	private CreateSequenceIdDao createUserNameDao;
	private StringBuffer str;
	private ConcurrentHashMap useDataMap;
	private ConcurrentHashMap surplusDataMap;
	private long memData;

	public CreateMysqlSequenceId() {
		str = new StringBuffer();
		useDataMap = new ConcurrentHashMap();
		surplusDataMap = new ConcurrentHashMap();
		createUserNameDao = new CreateSequenceIdDaoImpl();
	}

	@Override
	public long getSequenceId(int idcNum, int type, long memData) {
		long sequenceId = -1;
		/* 避免在并发环境下出现线程安全,则添加同步对象锁 */
		synchronized (this) {
			if (null != createUserNameDao) {
				this.memData = memData;
				/* idc机房编码数据长度必须为3位,type数据长度必须为2位 */
				if (3 == String.valueOf(idcNum).length() && 2 == String.valueOf(type).length()) {
					try {
						/* 根据指定的类别从内存中获取剩余的占位数量 */
						Integer surplusData = surplusDataMap.get(type);
						if (null != surplusData) {
							if (0 < surplusData) {
								surplusDataMap.put(type, --surplusData);
								Long useData = useDataMap.get(type);
								if (null == useData) {
									useData = createUserNameDao.queryUseDatabyType(type);
									useDataMap.put(type, useData);
									transactionManager();
								}
								/* 根据指定规则创建唯一的SequenceId */
								sequenceId = createSequenceId(useData - surplusData, idcNum, type);
							} else {
								/* 生成当前占位数据 */
								Long useData = createUseData();
								surplusData = (int) memData;
								/* 根据指定的类别更新当前占位数量 */
								createUserNameDao.changeUseData(type, useData);
								surplusDataMap.put(type, --surplusData);
								useDataMap.put(type, useData);
								transactionManager();
								sequenceId = createSequenceId(useData - surplusData, idcNum, type);
							}
						} else {
							Long useData = createUseData();
							surplusData = (int) memData;
							if (null != createUserNameDao.queryUseDatabyType(type)) {
								createUserNameDao.changeUseData(type, useData);
							} else {
								createUserNameDao.insertSequenceId(type, useData);
							}
							surplusDataMap.put(type, --surplusData);
							useDataMap.put(type, useData);
							transactionManager();
							sequenceId = createSequenceId(useData - surplusData, idcNum, type);
						}
					} catch (Exception e) {
						try {
							if (null != CreateSequenceIdDaoImpl.conn && !CreateSequenceIdDaoImpl.conn.isClosed()) {
								CreateSequenceIdDaoImpl.conn.rollback();
							}
						} catch (SQLException e1) {
							e1.printStackTrace();
						}
						throw new SequenceIdException("create sequenceid fail" + e.getMessage());
					} finally {
						try {
							if (null != CreateSequenceIdDaoImpl.conn && !CreateSequenceIdDaoImpl.conn.isClosed()) {
								DBConnectionManager.close(CreateSequenceIdDaoImpl.conn);
							}
						} catch (SQLException e) {
							e.printStackTrace();
						}
					}
				} else {
					throw new SequenceIdException("idc length must be equal to 3,type length must be equal to 2");
				}
			}
		}
		return sequenceId;
	}

	/**
	 * 进行事物传播特性控制的事物管理
	 * 
	 * @author gaoxianglong
	 * 
	 * @throws SQLException
	 * 
	 * @return void
	 */
	private void transactionManager() throws SQLException {
		CreateSequenceIdDaoImpl.conn.commit();
	}

	/**
	 * 生成当前占位数据
	 * 
	 * @author gaoxianglong
	 * 
	 * @throws Exception
	 * 
	 * @return long 返回生成的当前占位数据
	 */
	private long createUseData() throws Exception {
		/* 获取当前最大的占位数据 */
		Long useData = createUserNameDao.queryMaxUseData();
		return null != useData ? useData += memData : memData;
	}

	/**
	 * 根据指定规则创建唯一的userName
	 * 
	 * @author gaoxianglong
	 * 
	 * @param id
	 *            唯一序列
	 * 
	 * @param idcNum
	 *            IDC机房编码, 用于区分不同的IDC机房,3位数字长度
	 * 
	 * @param type
	 *            业务类别,2位数字长度
	 * 
	 * @return long 返回生成的19位数字长度的sequenceId
	 */
	private long createSequenceId(Long id, int idcNum, int type) {
		if (null != str)
			str.delete(0, str.length());
		final int length = 14 - String.valueOf(id).length();
		/* 唯一序列高位补0 */
		for (int i = 0; i < length; i++)
			str.append(0);
		str.append(id);
		str.insert(0, idcNum);
		str.insert(3, type);
		return Long.parseLong(str.toString());
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy