Chinaunix首页 | 论坛 | 博客
  • 博客访问: 6944687
  • 博文数量: 701
  • 博客积分: 10821
  • 博客等级: 上将
  • 技术积分: 12021
  • 用 户 组: 普通用户
  • 注册时间: 2005-12-02 10:41
个人简介

中科院架构师,专注企业数字化各个方面,MES/ERP/CRM/OA、物联网、传感器、大数据、ML、AI、云计算openstack、Linux、SpringCloud。

文章分类

全部博文(701)

分类: Oracle

2014-07-03 14:21:40

在数据库中自增是一个让人又爱又怨的功能。虽然Oracle、sqlserver、mysql都提供了自己的方法。但各个DB也都明确要求在一定的条件下,要用法正确。
下面介绍一下:Oracle的sequence自增中的问题及解决。
现象:
用 sequence 生成主键,cache 值设为20 。发现了一个异常,那就是生成的主键不连续,比如说上个数字是4551552,下个就成了4552838 ,差别实在是太大了。
我的代码里(java 工程,ibatis insert语句)调用该 sequence.nextval
只有一处啊,没有其他地方调用 nextval 。

解决:

可以确定是merge into 语句的问题了,在ibatis 配置文件中如下这么写是有问题的:

                       merge into tablename using
                         (select count(*) count from tablename where condition1) numcount
                       on (numcount.count <> 0)
                       when matched then
                         UPDATE SET A=A+1 WHERE  condition2
                       when not matched then
                         INSERT (ID,A,B,C,D)
                         VALUES(tablename_SEQUENCE.NEXTVAL,  #a#,  #b#,  #c#,  #d#  )
         ]]>
 

正确的写法是这样:

       
                
       

                       merge into tablename using
                         (select count(*) count from tablename where condition1) numcount
                       on (numcount.count <> 0)
                       when matched then
                         UPDATE SET A=A+1 WHERE  condition2
                       when not matched then
                         INSERT (ID,A,B,C,D)
                         VALUES(tableid,  #a#,  #b#,  #c#,  #d#  )
         ]]>
 

分析:
   http://hiyachen.blog.chinaunix.net
1:merge into tablename using (select count(*) count from tablename where condition1) numcount
      on (numcount.count <> 0)
之前也遇到过,序列值涨到 好几十亿 。这个条件的写法,满足update时,相当于全表都符合,会生成全表的序列。
危险举例:当tablename 达到几十万行记录以后, 可以把数据库搞挂了,CPU飙高

2:sequence的读取不是采用i++这种的形式,
1)系统会读取例如sequence:1-100到内存中去,用于insert操作,当用到50时候,电脑奔溃了。这个时候电脑重启后再进行insert插入则会读取101-200,而不是从51开始。
2)在进行insert操作时候,使用的是sequence:150,你突然rollback一次,那么下次使用的sequence是:151,这个时候150就被浪费了。

阅读(5009) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~