shardingsphere版本:4.1.1
mybatis版本:3.5.3
mybatis、shardingsphere、sharding-jdbc、shardingjdbc、批量插入、自增主键、分布式主键、排序不一致、desc、递增
INSERT INTO *** VALUES \ *** \
批量插入数据mysql
的自增主键unique_id
SNOWFLAKE
自动生成分布式唯一id,但是这个id和自增主键不是同一个字段CREATE TABLE
t_user_praise_
(
id
bigint(20) unsigned NOT NULL DEFAULT ‘0’ COMMENT ‘文章点赞表的id或者评论回复点赞表的id’,
article_id
bigint(20) unsigned NOT NULL DEFAULT ‘0’ COMMENT ‘文章id’,
record_id
bigint(20) unsigned NOT NULL DEFAULT ‘0’ COMMENT ‘文章id或者评论id或者回复id’,
praise_type
tinyint(3) unsigned NOT NULL DEFAULT ‘0’ COMMENT ‘点赞类型(1-点赞文章;2-点赞评论;3-点赞回复)’,
user_id
bigint(20) unsigned NOT NULL DEFAULT ‘0’ COMMENT ‘用户id’,
praise_status
tinyint(3) unsigned NOT NULL DEFAULT ‘0’ COMMENT ‘点赞状态(0-点赞;1-取消点赞)’,
unique_id
bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT ‘主键id’,
PRIMARY KEY (unique_id
),
UNIQUE KEYUIDX_UID_RID_TYPE
(user_id
,record_id
),
KEYIDX_ID
(id
)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT=‘我点赞的文章、评论、回复,按用户id分库’
<bean:properties id="properties">
<prop key="worker.id">123prop>
bean:properties>
<sharding:key-generator id="itemKeyGenerator" type="SNOWFLAKE" column="id" props-ref="properties" />
<sharding:inline-strategy id="t_user_praise_db" sharding-column="user_id" algorithm-expression="ds$->{user_id % 2}"/>
<sharding:inline-strategy id="t_user_praise_tb" sharding-column="user_id" algorithm-expression="t_user_praise_$->{user_id % 3}"/>
<sharding:table-rule logic-table="t_user_praise_" actual-data-nodes="ds$->{0..1}.t_user_praise_$->{0..2}"
database-strategy-ref="t_user_praise_db" key-generator-ref="itemKeyGenerator" table-strategy-ref="t_user_praise_tb"/>
@Transactional
@Override
public void test() {
UserPraise u1 = new UserPraise();
u1.setArticleId(1L);
u1.setRecordId(1L);
u1.setPraiseType(1);
u1.setUserId(1L);
u1.setPraiseStatus(1);
UserPraise u2 = new UserPraise();
u2.setArticleId(1L);
u2.setRecordId(2L);
u2.setPraiseType(1);
u2.setUserId(1L);
u2.setPraiseStatus(1);
List<UserPraise> uus = new ArrayList<>();
uus.add(u1);
uus.add(u2);
insertBatch(uus);
}
private void insertBatch( List<UserPraise> uus ) {
userPraiseMapper.insertBatch(uus);
}
<insert id="insertBatch">
INSERT INTO t_user_praise_ ( article_id,record_id,praise_type,user_id, praise_status)
VALUES
<foreach collection="lists" item="item" separator=",">
(#{item.articleId},#{item.recordId},#{item.praiseType},#{item.userId},#{item.praiseStatus})foreach>
insert>
<dependency>
<groupId>org.apache.shardingspheregroupId>
<artifactId>sharding-jdbc-spring-namespaceartifactId>
<version>${sharding-jdbc}version>
dependency>
<dependency>
<groupId>org.apache.shardingspheregroupId>
<artifactId>sharding-jdbc-coreartifactId>
<version>${sharding-jdbc}version>
dependency>
上述插入第一条记录id的值为
582575377823019009
,自增主键unique_id的值为1
第二条id的值为582575377823019008
,自增主键unique_id的值为2
很明显,自增unique_id为1
的记录的由SNOWFLAKE
生成的id竟比unique_id为2
的要大,按道理,他们的顺序应该是一样的。这就很奇怪了,于是,我便试图找出为什么。。。
由图1可知,确实为column为id的列生成了2个id
582590044029038593
和582590044029038594
,并且大小是由小到大
在组装sql语句之前,图2看起来也都正常
但是图3的时候,第一次就获取了比较大的那个generatedValue
让我们倒回去再看看
图4看起来没啥问题,获取迭代器的next的值,肯定是从小到大按顺序获取啊。。。这。。。
再往上研究下
真实柳暗花明又一村,原来这边使用了一个
descendingIterator
,这个就会导致使用迭代器获取数据的时候,按照desc降序来回去!
那我就不禁疑问了,这是坐着有意为之,还是。。。
于是,我又去github上苦苦找寻了一番。。。
真相,就在下面
看来已经有人反馈过类似的问题了,这个在旧版本是存在的,但是新版本
5.0.0-alpha
已经修复。只可惜这种问题,不怎么好用语言去描述,不然应该很容易就找到。我花了大半天时间才弄清原有并且在github上找到类似问题。。。555555555555
ps:shardingsphere的
5.0.0-alpha
版本的pom坐标 和4.1.1
以及以下的版本是不一样的,所以修改版本号的时候不仅仅要修改version
。这一点我也被坑了好久好久o(╥﹏╥)o。。。
另,附上github相关链接,点我
Multi-values insertion bug with key-generator in sharding databases/tables
Why do distributed primary keys need to be retrieved in reverse order in ShardingGeneratedKeyInsertValueParameterRewriter.rewrite
…