<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>业务开发 on Wimi's Space</title><link>https://wimi.space/tags/%E4%B8%9A%E5%8A%A1%E5%BC%80%E5%8F%91/</link><description>Recent content in 业务开发 on Wimi's Space</description><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Fri, 13 Jun 2025 20:44:39 +0800</lastBuildDate><atom:link href="https://wimi.space/tags/%E4%B8%9A%E5%8A%A1%E5%BC%80%E5%8F%91/index.xml" rel="self" type="application/rss+xml"/><item><title>版本号机制在业务中的应用</title><link>https://wimi.space/posts/2025/06/business-version-number/</link><pubDate>Fri, 13 Jun 2025 20:44:39 +0800</pubDate><guid>https://wimi.space/posts/2025/06/business-version-number/</guid><description>&lt;h2 id="版本号机制">版本号机制&lt;/h2>
&lt;p>使用版本号实现乐观锁是一种常见的做法，尤其在需要处理并发更新的场景中。以下是使用版本号实现乐观锁的步骤：&lt;/p>
&lt;ol>
&lt;li>添加版本号字段：在需要支持乐观锁的表中，添加一个版本号字段，通常是整型。&lt;/li>
&lt;li>读取数据时获取版本号：当读取记录时，同时获取该记录的版本号。&lt;/li>
&lt;li>更新数据时检查版本号：在更新记录之前，检查数据库中的版本号是否与之前读取的版本号一致。&lt;/li>
&lt;li>更新版本号：如果版本号一致，执行更新操作，并递增版本号。&lt;/li>
&lt;li>处理更新失败的情况：如果版本号不一致，说明记录已被其他事务更新，此时更新操作应该失败，并根据业务逻辑进行相应处理，比如重试或报错。&lt;/li>
&lt;/ol>
&lt;h2 id="项目举例">项目举例&lt;/h2>
&lt;h3 id="需求">需求&lt;/h3>
&lt;p>以账户余额增减的业务场景举例，使用版本号机制实现账户余额增减，同时生成账户流水。需要保证余额操作的最终一致性，在高并发场景下读写正确，在分布式环境下也不会有并发问题，实现省略用户登录态信息。&lt;/p>
&lt;h3 id="表结构设计">表结构设计&lt;/h3>
&lt;p>创建用户账户表和流水表，省略用户信息表。&lt;/p>

&lt;details>
 &lt;summary>表结构定义&lt;/summary>
 &lt;pre>&lt;code class="language-SQL">CREATE TABLE `account` (
 `id` bigint NOT NULL AUTO_INCREMENT,
 `user_id` bigint NOT NULL COMMENT '用户id',
 `balance` decimal(18,2) NOT NULL COMMENT '当前余额，精确到分',
 `version` int NOT NULL DEFAULT '0' COMMENT '版本号',
 `status` tinyint NOT NULL DEFAULT '1' COMMENT '账户状态（1：正常、2：冻结）',
 `created_at` datetime NOT NULL,
 `updated_at` datetime NOT NULL ON UPDATE CURRENT_TIMESTAMP,
 PRIMARY KEY (`id`),
 UNIQUE KEY `udx_uid` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

CREATE TABLE `account_flow` (
 `id` bigint NOT NULL AUTO_INCREMENT,
 `flow_no` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '流水号',
 `account_id` bigint NOT NULL COMMENT '关联的账户id',
 `amount` decimal(18,2) NOT NULL COMMENT '变动金额（正：进账，负：出账）',
 `balance_before` decimal(18,2) NOT NULL COMMENT '变动前余额',
 `balance_after` decimal(18,2) NOT NULL COMMENT '变动后余额',
 `type` tinyint NOT NULL COMMENT '流水类型（1：充值、2：消费、3：退款、4：提现）',
 `biz_no` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '业务单号',
 `version_seq` int NOT NULL COMMENT '关联账户的版本号（用于追溯）',
 `created_at` datetime NOT NULL ON UPDATE CURRENT_TIMESTAMP,
 PRIMARY KEY (`id`),
 UNIQUE KEY `udx_fno` (`flow_no`),
 KEY `idx_aid_cat` (`account_id`,`created_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
&lt;/code>&lt;/pre>
&lt;/details>

&lt;p>假设一个用户只能有一个账户，对用户 ID 创建唯一索引。流水表记录操作关联的版本和变动前后余额，方便追溯操作和统计分析。流水号全局唯一，示例用 UUID（具体业务可使用分布式 ID 来保证唯一性）同时创建了唯一索引约束，其他索引可根据业务需求自行增加。&lt;/p></description></item></channel></rss>