好贷网好贷款

多线程同时访问一张表记录最大值,并插入新记录为最大值加1

发布时间:2016-12-4 20:11:06 编辑:www.fx114.net 分享查询网我要评论
本篇文章主要介绍了"多线程同时访问一张表记录最大值,并插入新记录为最大值加1",主要涉及到多线程同时访问一张表记录最大值,并插入新记录为最大值加1方面的内容,对于多线程同时访问一张表记录最大值,并插入新记录为最大值加1感兴趣的同学可以参考一下。

最近要做一个进件模块,就是写页面录资料。 其中有个字段协议编号,是12位数字,对于每个用户名都是从0000 0000 0001 开始,依次递增。 基本方法是先从数据库根据用户名,查询记录的该字段最大值,然后增加1,插入进去。 一开始我用java的synchronized ,结果发现问题依然存在,就是该字段同一个用户名有重复。 网上一查才知道synchronized 锁定的是同一个对象,而spring Ioc注入的service对象都是ThreadLocal的 也就是说每一个线程,service对象不一样。 现在采用是加事务锁。 事务有4种隔离级别:read uncommitted,read committed,repeatable read,serializable。 数据并发有五个问题:脏读,不可重复读,幻象读,第一类丢失更新,第二类丢失更新。 每种隔离级别分别允不允许这五种问题出现,自己去查表。 我这种情况,是先查询,再新增,属于”幻象读“这种问题。而只有最高级serializable才不允许幻象读。 @Transactional(isolation=Isolation.SERIALIZABLE) public void insertOne(Sector sector) { // TODO Auto-generated method stub long max=findMaxName(); StringBuilder sb=new StringBuilder(); for(int i=0;i<12-((max+1)+"").length();i++){ sb.append("0"); } sb.append(max+1); sector.setName(sb.toString()); sectorDao.save(sector); } @Test public void myTest() { //测试多线程,同时访问一张表记录,并插入新数据。 //2个线程同时读取sector记录的name最大值,然后插入最大值加1的一条记录 new Thread(){ @Override public void run() { try { // TODO Auto-generated method stub sectorService.insertOne(new Sector()); //Thread.sleep(1000); } catch (Exception e) { System.out.println("1 fail"); } } }.start(); new Thread(){ @Override public void run() { try { //Thread.sleep(400); // TODO Auto-generated method stub sectorService.insertOne(new Sector()); } catch (Exception e) { System.out.println("2 fail"); } } }.start(); new Thread(){ @Override public void run() { try { //Thread.sleep(600); // TODO Auto-generated method stub sectorService.insertOne(new Sector()); } catch (Exception e) { System.out.println("3 fail"); } } }.start(); }测试结果: Hibernate:      insert      into         oa_sector         (memberId, name)      values         (?, ?) 1 fail 2 fail 说明第3个线程插入进去了。 在前端页面,如果失败可以提示”服务器繁忙,提交失败,请重试“。

上一篇:14 MVCC的可见性
下一篇:Java中的随机数解说

相关文章

相关评论