最近的项目使用SSH开发一个Web应用,使用Mysql5数据库,为了提高性能配置Hibernate参数hibernate.jdbc.batch_size,但是总是出现主键冲突问题,后来关闭了这个参数hibernate.jdbc.batch_size=0,仍然出现这个问题,很是费劲,起初是怀疑Mysql本身的问题,看来不是这个问题!突然想到Hibernate3主键产生的方式,发现对应increment主键生成器的org.hibernate.id.IncrementGenerator 类里面,是使用select max( columnName ) from tableName的方式来获取。原来的程序一直运行很好,但是在用两个Tomcat来负载均衡后却出现问题。为什么?IncrementGenerator类里面的generate()方法虽然被声明成了synchronized,但现在两个Tomcat分别运行在两台服务器的两个独立的Java虚拟机里,显然问题在这里,synchronized只能在一个独立的Java虚拟机内部有效。所以,在两个Tomcat 中用select max同时取主键,就相当于在没有synchronized的保护下,并发时就会取出相同的值,再insert就会发生dumplicate entry的错误。
后来查看Hibernate的Reference中也提到,increment不要再集群下使用。
问题找到了,解决的办法也很简单,就是使用MySQL自己的auto_increment功能来产生主键。只需将所有Hibernate映射文件中的increment改为native或者identity。并将数据库的主键加上auto_increment属性。
Hibernate3主键冲突问题
最新推荐文章于 2020-11-04 22:17:45 发布