NUMBER_GET_NEXT流水号跳号的问题

本文介绍了解决在使用NUMBER_GET_NEXT获取流水号时出现跳号问题的方法。通过调整缓存设置,并在调用FUNCTION时设置ignore_buffer参数为X,可以有效避免因缓存导致的流水号不连续现象。
部署运行你感兴趣的模型镜像

我们在用NUMBER_GET_NEXT取得流水号的时候,经常由于缓存的原因导致跳号现象的发生,只要简单的设置即可解决这样的问题:

1.把缓存数设置为0.这个在SNRO里进行设置。一般这样就可以解决问题。如果还存在这种现象:

2.    call function 'NUMBER_GET_NEXT'
      exporting
        nr_range_nr             = '01'
        object                  = 'ZYFK_NUM'
        ignore_buffer           = 'X'

把FUNCTION里的ignore_buffer           = 'X'设置为X即可解决

您可能感兴趣的与本文相关的镜像

Stable-Diffusion-3.5

Stable-Diffusion-3.5

图片生成
Stable-Diffusion

Stable Diffusion 3.5 (SD 3.5) 是由 Stability AI 推出的新一代文本到图像生成模型,相比 3.0 版本,它提升了图像质量、运行速度和硬件效率

### 问题分析 您的代码使用了悲观锁 (`FOR UPDATE`) 来保证流水号的连续性,但依然存在以下几个关键问题: 1. **流水号浪费问题** - 在 `UPDATE` 增加流水号后,如果后续业务逻辑失败(比如保存商机数据失败),这个流水号就浪费了,导致。 2. **业务层唯一约束的依赖** - 您提到商机编需要存入另一个表,并且要求不能,直接 `UPDATE` 流水号后返回,如果业务保存失败,流水号已经被消耗,无法回滚。 3. **事务边界问题** - 当前的事务只包含流水号的更新,不包含业务数据的保存,无法做到原子性。 --- ### ✅ **解决方案(保证严格不)** #### **方案1:事务包裹业务逻辑(推荐)** ```java while (true) { try (Connection conn = dataSource.getConnection()) { conn.setAutoCommit(false); // 开启事务 // 1. 锁定并获取当前流水号 PreparedStatement queryStmt = conn.prepareStatement( "SELECT CURRENT_SERIAL FROM ebs_serial_number " + "WHERE BIZ_DATE = CURDATE() FOR UPDATE"); ResultSet rs = queryStmt.executeQuery(); int newSerial; if (rs.next()) { newSerial = rs.getInt(1) + 1; // 2. 预占流水号(但不立即更新) } else { newSerial = 1; // 3. 初始化记录 PreparedStatement insertStmt = conn.prepareStatement( "INSERT INTO ebs_serial_number VALUES (?, CURDATE(), 1, 0)"); insertStmt.setString(1, IdUtil.simpleUUID()); insertStmt.executeUpdate(); } // 4. 生成商机编 String bizNum = String.format("QT%s%03d", dateStr, newSerial); // 5. 尝试业务操作(如保存商机数据) boolean bizSuccess = saveBizData(conn, bizNum); // 业务方法需使用同一连接 if (bizSuccess) { // 6. 业务成功后才正式占用流水号 PreparedStatement updateStmt = conn.prepareStatement( "UPDATE ebs_serial_number SET CURRENT_SERIAL = ? " + "WHERE BIZ_DATE = CURDATE()"); updateStmt.setInt(1, newSerial); updateStmt.executeUpdate(); conn.commit(); return bizNum; } else { conn.rollback(); throw new RuntimeException("业务操作失败"); } } catch (SQLException e) { if (e.getErrorCode() == 1062) continue; // 唯一冲突重试 throw new RuntimeException("系统错误", e); } } ``` #### **关键改进点:** 1. **事务包含业务操作** - 使用同一个连接保证流水号更新和业务操作在同一个事务中 - 只有业务成功后才提交流水号变更 2. **预占但不立即更新** - 先计算 `newSerial`,但等业务确认成功后再更新数据库 3. **严格避免** - 任何业务失败都会导致事务回滚,流水号不会被消耗 --- ### ⚠️ **注意事项** 1. **业务方法必须使用同一连接** ```java boolean saveBizData(Connection conn, String bizNum) { // 必须使用参数传入的conn执行SQL } ``` 2. **事务隔离级别建议** ```java conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED); ``` 3. **分布式环境限制** - 该方案仅适用于单机或共享数据库的集群 - 如需分布式方案需改用Redis/Tair等分布式序列服务 --- ### 📊 **备选方案对比** | 方案 | 连续性 | 实现复杂度 | 适用场景 | |--------------------|--------|------------|-------------------------| | 事务包裹业务(推荐) | 绝对连续 | 中 | 严格不允许的业务 | | 状态标记法 | 连续 | 高 | 需要回收机制的复杂系统 | | 预占+异步回收 | 基本连续 | 中 | 允许短暂不一致的业务 | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值