1.在mysql数据库中读取该数据的时候,会出现脏读,即写操作是基于读,并发的同时,导致一个读写没有完成一个新的读写又开始了.
解决:在方法上加事务隔离,防止脏读
@Transactional(isolation = Isolation.READ_COMMITTED)
在方法上加一个异步锁
synchronized
注意:读写操作需要在同一个事务中,这样,另一个事务过来后才会被这个线程阻塞.
业务逻辑代码写在service层,勿写在controller层.
@Override
@Transactional(isolation = Isolation.READ_COMMITTED)
public synchronized String selectBindTelxAreacodeByNum() {
if(deque.size() == 0){
//读
List<BindTelxAreacode> telxAreacodes= bindTelxAreacodeMapper.seletcAllOrderByNum();
for (BindTelxAreacode telxAreacode : telxAreacodes) {
deque.add(telxAreacode);
}
}
BindTelxAreacode telxAreacode = deque.pop();
telxAreacode.setId(telxAreacode.getId());
telxAreacode.setTelx(telxAreacode.getTelx());
Long num = telxAreacode.getNum()+1L;
telxAreacode.setNum(num);
telxAreacode.setUpdateTime(DateUtils.getNowDate());
//写
bindTelxAreacodeMapper.updateBindTelxAreacode(telxAreacode);
deque.add(telxAreacode);
return telxAreacode.getTelx();
}
2.使用队列,作为数据桶,用于数据的抽取,不从数据库查询,因队列是单线程的,所以,有效优化并发问题.
伪代码:
(1)创建一个Deque队列
public static Deque<BindTelxAreacode> deque = new ArrayDeque();
(2)判断队列中是否为空,如果为空,从数据库中按照使用次数的大小,从小到大全部查询出来
select id, code, remark, num from table order by num asc
查询出来后用for循环,将查询出的对象都add()到队列中,相当于加数据到队列中,
(3)如果说队列中有数据,不管数据是多少,对数据进行pop()数据,取一个数据,
取到这个数据,将num+1,然后又保存到数据库中,即这个数据被使用了.
然后再把这个数据(+1后)add()到队列中.
(4)这个数据取到后return出去.
--综上所述,该这就是将数据拿到系统上,不从数据库中查询数据.