mongodb java下自增 id的实现

mongodb没有关于自增id的实现

1。一般思路是取出最大的id ,然后+1。  除非取最大的id和+1这两个步骤是原子的,否则一定存在并发问题(有可能两个线程同时取到一个id),显然这样不可取。

2。另外,也可以将插入和具体程序解耦, 将所有的插入操作提交到一个可阻塞的队列,然后多个线程不断的消费这个队列。  由这个队列控制生成id,这样不会存在同步问题。 但是当有大量的插入操作时,消费线程变多,会在对头有很大竞争。

3 。也可以在程序启动的时候初始化一个collection的最大 id, 然后原子的去更新这个id

public class UserCollection {
	private static final String collectionName = "user";
	private final AtomicInteger maxId = new AtomicInteger();
	
	
	// single instance
	private static UserCollection collection = new UserCollection();
	private UserCollection() {
		int max = MongoUtil.getMaxId(collectionName);
		maxId.set(max);
	}
	public static UserCollection getInstance(){
		return collection;
	}
	
	public int  getIncreasedId() {
		return maxId.getAndIncreased()
	}
}

对于多个collection的情况,可以用map去保存collectionName 和maxId 之间的对于关系(可以lazy init)。 然后提供统一的接口  

public class MongoIdUtil {
	private final ConcurrentHashMap<String, Integer> nameAndId = new ConcurrentHashMap<String, Integer>();
	
	public int getIncreasedId(String name) {
		for(;;) {
			Integer id = nameAndId.get(name);
			if(id == null) {
				DBCollection collection = MongoUtil.getCollection(name);
				if(collection == null) 
					throw new RuntimeException("mongo collection with name: " + name + "not exist!");
				@SuppressWarnings("unchecked")
				List<Integer> distinct = collection.distinct("id");
				int maxId = Collections.max(distinct) + 1;
				if(nameAndId.putIfAbsent(name, maxId) != null) continue;//loop when failure
				return maxId;
			}
			int newId = id + 1;
			if(nameAndId.replace(name, id, newId)) {
				return newId;
			}
		}
	}
	
	private MongoIdUtil() {};
	private static MongoIdUtil instanse = new MongoIdUtil();
	public static MongoIdUtil getInstance() {
		return instanse;
	}
}



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值