InnoDB和MyISAM对比,以及InnoDB行锁使用(生成唯一id)

InnoDB:有事务、支持行锁,适用于并发处理的业务。针对单个操作,因为有事务(即使查询也是自动提交一个事务),相对开销大,但支持并发处理不同行数据,所以吞吐量大。

MyISAM:无事务,表锁,适合少量并发操作。针对单个操作,因为无事务,表锁时间开销小,读取速度快。但崩溃不可恢复,所以一般用于不重要的,或只供查询的业务使用。

        对于集群分布式服务来说,需要保证某个服务的表的唯一id,假设不再使用mysql的自增id。有很多方式,这里举例一个。为了避免频繁读取可用id,集群中每个服务器每次取一定量的可用的id范围,不够了再取。

方案:主库建新表存储唯一id的信息,目前值、每次取得值范围。

service:

@Service
public class AutoNumberImplService implements AutoNumberService {
	private ConcurrentHashMap<String, AutoNumberItem> type2AutoNumberMap = new ConcurrentHashMap<String, AutoNumberItem>();

	@Resource
	private AutoNumberDao dao;

	@Override
	public int getNextNumber(AutoNumberType type) {
		return getNextNumber(type, false);
	}

	public int getNextNumber(AutoNumberType type, boolean needFromDB) {
		AutoNumberItem item = type2AutoNumberMap.get(type.name);
		if (needFromDB || item == null) {
			AutoNumberItem newStep = getNewStep(type);
			type2AutoNumberMap.putIfAbsent(type.name, newStep);
			item = newStep;
		}

		int next = item.getNext();
		int maxNumber = item.getMax();
		if (next > maxNumber) {
			return getNextNumber(type, true);
		}
		return next;
	}

	@Transactional
	private AutoNumberItem getNewStep(AutoNumberType type) {
		AutoNumberItem item = dao.select(type.name);
		item = new AutoNumberItem(item.getStart(), item.getStep());//事务里查询出来的结果适用空构造函数,所以对象的其他值为默认值
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("name", type.name);
		params.put("inc", item.getStep());
		dao.update(params);
		return item;
	}

}

 model:

public class AutoNumberItem {
	private int start;
	private int step;
	private int max;
	private int now;

	public AutoNumberItem() {
	}
	
	//奇葩的是,mybites查询出来适用默认构造函数
	public AutoNumberItem(int start, int step) {
		this.start = start;
		this.step = step;
		this.max = this.start + this.step;
		this.now = start;
	}

	public synchronized int getNext() {
		now += 1;
		return now;
	}

	public int getMax() {
		return this.max;
	}

	public int getStart() {
		return start;
	}

	public int getStep() {
		return step;
	}
}

 

 

 配置文件:

<mapper namespace="com.liu.dao.AutoNumberDao">  

	<resultMap type="com.liu.model.AutoNumberItem" id="itemMap">
		<result column="Start" property="start" />
		<result column="Step" property="step" />
	</resultMap>
     <!-- mybsits_config中配置的alias类别名,也可直接配置resultType为类路劲 -->    
    <select id="select" parameterType="String" resultMap="itemMap">  
    <![CDATA[ 
        select Start,Step from autonumber where name=#{name} FOR UPDATE
    ]]>
    </select> 
    
    <insert id="insert" parameterType="com.liu.model.AutoNumberItem" flushCache="true">  
        insert into autonumber (Name, Start, Step) values (#{name,jdbcType=VARCHAR}, #{start,jdbcType=INTEGER}, #{step,jdbcType=INTEGER})  
    </insert>
    
    <update id="update">
		update autonumber
		<trim prefix="set" suffixOverrides=",">
			<if test="inc!=null">start=start+#{inc,jdbcType=INTEGER},</if>
		</trim>
		where Name=#{name,jdbcType=VARCHAR}
	</update> 
      
</mapper> 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值