Mysql提供sequence服务

使用mysql提供sequence的服务,我们在执行的一个方案:

1:创建sequence相关表

CREATE TABLE `seq_order_id` (
  `seq` bigint(20) NOT NULL AUTO_INCREMENT,
  `stub` varchar(3) NOT NULL,
  PRIMARY KEY (`seq`),
  UNIQUE KEY `stub` (`stub`)
) ENGINE=InnoDB AUTO_INCREMENT=10000 DEFAULT CHARSET=utf8;

2:获取seq时相关SQL:

REPLACE INTO seq_order_id(stub) VALUES (#stub#)
SELECT last_insert_id()

这种方式可以一个表提供给多个业务做seq的服务,但是由于REPLACE INTO会有锁表状况存在,在业务量很大时,对数据库的性能影响较大。

3:修改为使用spring的org.springframework.jdbc.support.incrementer.MySQLMaxValueIncrementer,方法加了同步锁,每次数据库操作会直接获取一个段的值cacheSize,业务分布式部署也不影响sequence的唯一性

    @Override
	protected synchronized long getNextKey() throws DataAccessException {
		if (this.maxId == this.nextId) {
			/*
			* Need to use straight JDBC code because we need to make sure that the insert and select
			* are performed on the same connection (otherwise we can't be sure that last_insert_id()
			* returned the correct value)
			*/
			Connection con = DataSourceUtils.getConnection(getDataSource());
			Statement stmt = null;
			try {
				stmt = con.createStatement();
				DataSourceUtils.applyTransactionTimeout(stmt, getDataSource());
				// Increment the sequence column...
				String columnName = getColumnName();
				stmt.executeUpdate("update "+ getIncrementerName() + " set " + columnName +
						" = last_insert_id(" + columnName + " + " + getCacheSize() + ")");
				// Retrieve the new max of the sequence column...
				ResultSet rs = stmt.executeQuery(VALUE_SQL);
				try {
					if (!rs.next()) {
						throw new DataAccessResourceFailureException("last_insert_id() failed after executing an update");
					}
					this.maxId = rs.getLong(1);
				}
				finally {
					JdbcUtils.closeResultSet(rs);
				}
				this.nextId = this.maxId - getCacheSize() + 1;
			}
			catch (SQLException ex) {
				throw new DataAccessResourceFailureException("Could not obtain last_insert_id()", ex);
			}
			finally {
				JdbcUtils.closeStatement(stmt);
				DataSourceUtils.releaseConnection(con, getDataSource());
			}
		}
		else {
			this.nextId++;
		}
		return this.nextId;
	}
<bean id="orderIdSeqGenerater" class="org.springframework.jdbc.support.incrementer.MySQLMaxValueIncrementer">
    <property name="incrementerName" value="seq_order_id"/> 
    <property name="columnName" value="seq"/>
    <property name="cacheSize" value="1000"/>
    <property name="dataSource" ref="dataSource"/>
</bean>

 

转载于:https://my.oschina.net/dreamnight/blog/729777

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值