代码的实现轻微伟大一点,获取 ID 会按照营业标识 sequencename,先从内存获取 Step 的 ID 段,假如为 null,则从数据库中读取当前最新的值,并按照步长计较 Step,然后返回哀求 ID。假如从内存中直接获取到 Step,则直接取 ID,并对 currentValue 举办加一。当 currentValue 的值高出 endValue 时,则更新数据库的 ID,从头计较 Step。
- private Map<String,Step> stepMap = new HashMap<String, Step>();
- public synchronized long get(String sequenceName) {
- Step step = stepMap.get(sequenceName);
- if(step ==null) {
- step = new Step(startValue,startValue+blockSize);
- stepMap.put(sequenceName, step);
- } else {
- if (step.currentValue < step.endValue) {
- return step.incrementAndGet();
- }
- }
- if (getNextBlock(sequenceName,step)) {
- return step.incrementAndGet();
- }
- throw new RuntimeException("No more value.");
- }
- private boolean getNextBlock(String sequenceName, Step step) {
- // "select id from sequence_value where name = ?";
- Long value = getPersistenceValue(sequenceName);
- if (value == null) {
- try {
- // insert into sequence_value (id,name) values (?,?)
- value = newPersistenceValue(sequenceName);
- } catch (Exception e) {
- value = getPersistenceValue(sequenceName);
- }
- }
- // update sequence_value set id = ? where name = ? and id = ?
- boolean b = saveValue(value,sequenceName) == 1;
- if (b) {
- step.setCurrentValue(value);
- step.setEndValue(value+blockSize);
- }
- return b;
- }
行使该要领获取 ID 可以镌汰对数据库的会见量,以低落数据库的压力,可是同样必要留意,获取 ID 同样存眷数据库事宜题目,由于当体系重启的时辰,stepMap 为 null,以是会取数据库查询当前 ID,更计较更新 Step,然后更新数据库的 ID。假如该要领被放到数据库事宜里,因为其他要领机能慢了,导致查询之后没有实时更新,并发环境下另一个线程查询的时辰,也许会获取到该线程未提交的 ID,因而呈现两个线程获取到沟通的 ID 题目。
本文小结
订单号天生是一个很是简朴的成果,可是在高并发的场景下,高机能和高可用就成为了必要存眷的要点。以是,现实事变中的每一个小细节都值得我们去深思。
(编辑:湖南网)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|