private SeqNo getOrCreate(String id) { SeqNo seq = db.session().get(SeqNo.class, id, LockMode.PESSIMISTIC_WRITE); if (seq == null) { create (id); seq = db.session().get(SeqNo.class, id, LockMode.PESSIMISTIC_WRITE); } return seq; }
/** * Synchronous 'reset' * @param id sequencer id * @param value reset value */ public void reset (String id, long value) { getOrCreate(id).setValue(value); }
/** * Asynchronous 'next' * * @param id sequencer ID * @param lockedBy unique client identifier (any long, has to be system-wide unique) * @param lockTimeout once lock is obtained, keep it fo 'lockTimeout' millis (if not 'released' earlier) * @param timeout time (in millis) to wait for this lock * @param wrapAt wrap at value * @return next sequencer value * @throws LockTimeoutException if lock can't be obtained after 'timeout' has elapsed */ public long next (String id, long lockedBy, long lockTimeout, long timeout, long wrapAt) { return lock (id, lockedBy, lockTimeout, timeout, seq -> seq.next(wrapAt)); }
private long nextAsync(long id, long delay) { SeqNoManager mgr = new SeqNoManager(new DB()); long l = mgr.next("sync", id, 60000L, 60000L, 999999L); ISOUtil.sleep(delay); mgr.release("sync", id); return l; } private void reset() {
private void reset() { try (DB db = new DB()) { SeqNoManager mgr = new SeqNoManager(db); db.open(); db.beginTransaction(); mgr.reset("sync", 0L); db.commit(); } } }
private long next(long delay) { try (DB db = new DB()) { SeqNoManager mgr = new SeqNoManager(db); db.open(); db.beginTransaction(); long l = mgr.next("sync", 999999L); ISOUtil.sleep(delay); db.commit(); return l; } }
/** * Synchronous 'next' * @param id sequencer id * @param wrapAt wrap at value * @return next sequencer value */ public long next (String id, long wrapAt) { return getOrCreate(id).next(wrapAt); }
/** * Reset an async lock * @param id lock ID * @param lockedBy unique client identifier * @param value new sequencer value * @param release if true, lock is released after reset * @throws LockTimeoutException if lock can't be obtained after 'timeout' has elapsed */ public void reset (String id, long lockedBy, long value, boolean release) { lock(id, lockedBy, 0L, 1000L, seq -> { seq.setValue(0L); if (release) seq.setLockedBy(0L); return 0L; }); }
/** * Release an async lock * @param id lock ID * @param lockedBy unique client identifier */ public boolean release (String id, long lockedBy) { if (db.session != null && db.session.isOpen()) throw new IllegalStateException("DB should not be open"); try (DB db1 = db) { db1.open(); db1.beginTransaction(); SeqNo seq = getOrCreate(id); if (seq.getLockedBy() == lockedBy && seq.getLockUntil() > System.currentTimeMillis()) { seq.setLockedBy(0L); db1.commit(); return true; } } return false; }
db1.open(); db1.beginTransaction(); SeqNo seq = getOrCreate(id); long now = System.currentTimeMillis(); if (seq.getLockedBy() == 0 || seq.getLockedBy() == lockedBy || seq.getLockUntil() < now) {