Backend Development 9 min read

Design and Implementation of a Generic Asynchronous Processing SDK for Java Backend

This article introduces a generic asynchronous processing SDK for Java backend systems, explaining its design principles, components, configuration, usage patterns, and advantages such as non‑intrusive design, transaction safety, and eventual consistency, while providing code samples, database scripts, and deployment details.

Architect
Architect
Architect
Design and Implementation of a Generic Asynchronous Processing SDK for Java Backend

Good system design must follow the open‑closed principle; as business evolves, core code changes frequently, increasing error risk. Most new features extend existing functionality, requiring both performance and quality, so developers often use asynchronous thread pools, which add uncertainty. To address this, a generic asynchronous processing SDK was designed to simplify various async scenarios.

Purpose : Ensure methods execute reliably without blocking the main flow and guarantee data is not lost, achieving eventual consistency.

Advantages :

Non‑intrusive design with independent database, scheduled tasks, message queue, and manual execution UI (single sign‑on).

Uses Spring transaction event mechanism; even if async strategy parsing fails, business logic remains unaffected.

If a method runs within a transaction, the async event is processed after commit or rollback.

Fallback execution ensures events are handled when no transaction is active.

Provides backup execution unless the database, message queue, or method itself fails.

Principle : After bean initialization, the container scans all methods for the @AsyncExec annotation and caches them. At runtime, an AOP interceptor publishes events, and a transactional event listener processes the async execution strategy.

@TransactionalEventListener(fallbackExecution = true, phase = TransactionPhase.AFTER_COMPLETION)

fallbackExecution=true : Process the event even when no transaction is active.

TransactionPhase.AFTER_COMPLETION : Handle the event after transaction commit or rollback.

Components :

Kafka message queue

XXL‑Job scheduled tasks

MySQL database

Spring AOP

Vue UI

Design Patterns employed include Strategy, Template Method, and Dynamic Proxy.

Database Scripts define three tables: async_scene (async scenarios), async_req (async requests), and async_log (execution logs). The scripts create primary keys, unique constraints, and timestamps for tracking.

CREATE TABLE `async_scene` (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `application_name` varchar(100) NOT NULL DEFAULT '' COMMENT '应用名称',
  `method_sign` varchar(50) NOT NULL DEFAULT '' COMMENT '方法签名',
  `scene_name` varchar(200) NOT NULL DEFAULT '' COMMENT '业务场景描述',
  `async_type` varchar(50) NOT NULL DEFAULT '' COMMENT '异步策略类型',
  `queue_name` varchar(200) NOT NULL DEFAULT '' COMMENT '队列名称',
  `theme_value` varchar(100) NOT NULL DEFAULT '' COMMENT '消费主题',
  `exec_count` int NOT NULL DEFAULT '0' COMMENT '失败重试次数',
  `exec_deleted` int NOT NULL DEFAULT '0' COMMENT '执行后是否删除',
  `async_version` varchar(50) NOT NULL DEFAULT '' COMMENT '组件版本号',
  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间',
  `cdc_crt_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '记录新增时间',
  `cdc_upd_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '记录修改时间',
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE KEY `uk_application_sign` (`application_name`,`method_sign`) USING BTREE,
  KEY `idx_cdc_upd_time` (`cdc_upd_time`)
) ENGINE=InnoDB COMMENT='异步场景表';

Async Strategy configuration includes thread pool sizes, queue capacity, keep‑alive time, retry counts, and security settings, all defined in a properties file.

# Switch (default off)
async.enabled=true

# Application name
spring.application.name=xxx

# DataSource (Druid)
async.datasource.driver-class-name=com.mysql.jdbc.Driver
async.datasource.url=jdbc:mysql://127.0.0.1:3306/fc_async?... 
async.datasource.username=user
async.datasource.password=xxxx

# Thread pool settings
async.executor.thread.corePoolSize=10
async.executor.thread.maxPoolSize=50
async.executor.thread.queueCapacity=10000
async.executor.thread.keepAliveSeconds=600

# Execution settings
async.exec.deleted=true
async.topic=${spring.application.name}
async.exec.count=5
async.retry.limit=100
async.comp.limit=100
async.login=false

Usage :

Enable async via scm.async.enabled=true .

Annotate methods with @AsyncExec(type = AsyncExecEnum.SAVE_ASYNC, remark = "Data Dictionary") (must be Spring‑proxied).

Access the manual handling UI at http://localhost:8004/async/index.html .

Notes :

Application name must be set.

Queue name defaults to the application name prefix.

Business logic should be idempotent.

All services share a single queue per application.

Self‑producing and self‑consuming design.

Scheduled tasks handle retry (every 2 minutes) and compensation (hourly) with configurable limits.

Effect Demonstration includes screenshots of the UI and workflow diagrams (images omitted).

GitHub Repository : https://github.com/xiongyanokok/fc-async

The article ends with a call to share, follow the author, and a disclaimer about content source.

backenddesign patternsJavaSpringasynchronous processing
Architect
Written by

Architect

Professional architect sharing high‑quality architecture insights. Topics include high‑availability, high‑performance, high‑stability architectures, big data, machine learning, Java, system and distributed architecture, AI, and practical large‑scale architecture case studies. Open to ideas‑driven architects who enjoy sharing and learning.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.