展示 HN: DBOS Java – 基于 Postgres 的持久工作流
Show HN: DBOS Java – Postgres-Backed Durable Workflows

原始链接: https://github.com/dbos-inc/dbos-transact-java

## DBOS:基于Postgres的可持久化工作流 DBOS是一个轻量级库,用于在Java应用程序中构建可靠的、长期运行的工作流,利用Postgres数据库的强大功能。它确保您的代码能够承受崩溃、重启和故障,而不会丢失进度或重复工作。 DBOS不是采用复杂的重试逻辑,而是在Postgres中检查点工作流状态,允许程序从任何中断中无缝恢复,并从中断的地方继续执行。这非常适合AI代理、数据管道、支付以及任何持续数分钟、数天或数周的流程等应用。 主要功能包括:**持久化队列**用于分布式任务管理,**持久化调度**支持cron语法,以及**持久化通知**用于可靠的事件驱动工作流——所有这些都不需要单独的服务或编排器。DBOS可以轻松地与现有的项目和框架(如Spring)集成,并利用熟悉的Postgres工具。 本质上,DBOS通过在应用程序代码中直接提供一致的可持久化执行模型,简化了构建容错系统的过程。

## DBOS Java:基于Postgres的持久化工作流 DBOS Java是一个新的开源库,旨在用Java构建可靠的、长期运行的工作流。它通过将每个步骤的检查点存储在Postgres数据库中,确保代码在失败(崩溃、重启)时能够存活,并且不会丢失进度,从而可以从上次已知状态恢复。 这简化了构建AI代理、支付和数据同步等任务的系统——任何需要长时间执行的任务。与临时重试逻辑不同,DBOS提供了一致的故障恢复模型。 该库可以与Spring等现有Java框架无缝集成,并利用熟悉的Postgres工具。一个关键特性是其自包含性;它只需要Postgres,避免了对独立服务或编排器的需求。一个Web UI(Conductor)目前作为托管服务可用,自托管版本即将推出。开发者正在积极寻求反馈,并讨论未来对其他数据库和语言(如.NET和Clojure)的支持。
相关文章

原文

DBOS provides lightweight durable workflows built on top of Postgres. Essentially, it helps you write long-lived, reliable code that can survive crashes, restarts, and failures without losing state or duplicating work.

As your workflows run, DBOS checkpoints each step they take in a Postgres database. When a process stops (fails, intentionally suspends, or a machine dies), your program can recover from those checkpoints to restore its exact state and continue from where it left off, as if nothing happened.

In practice, this makes it easier to build reliable systems for use cases like AI agents, data synchronization, payments, or anything that takes minutes, days, or weeks to complete. Rather than bolting on ad-hoc retry logic and database checkpoints, DBOS workflows give you one consistent model for ensuring your programs can recover from any failure from exactly where they left off.

This library contains all you need to add durable workflows to your program: there's no separate service or orchestrator or any external dependencies except Postgres. Because it's just a library, you can incrementally add it to your projects, and it works out of the box with frameworks like Spring. And because it's built on Postgres, it natively supports all the tooling you're familiar with (backups, GUIs, CLI tools) and works with any Postgres provider.

💾 Durable Workflows

Workflows make your program durable by checkpointing its state in Postgres. If your program ever fails, when it restarts all your workflows will automatically resume from the last completed step.

You add durable workflows to your existing Java program in just a few lines of code by registering ordinary functions as workflows and steps:

interface Example {
    public void workflow();
}

class ExampleImpl implements Example {

    private void stepOne() {
        System.out.println("Step one completed!");
    }

    private void stepTwo() {
        System.out.println("Step two completed!");
    }

    @Workflow()
    public void workflow() {
        DBOS.runStep(() -> stepOne(), "stepOne");
        DBOS.runStep(() -> stepTwo(), "stepTwo");
    }
}

Workflows are particularly useful for

  • Orchestrating business processes so they seamlessly recover from any failure.
  • Building observable and fault-tolerant data pipelines.
  • Operating an AI agent, or any application that relies on unreliable or non-deterministic APIs.

Read more ↗️

📒 Asynchronous execution

You can run your workflows asynchronously without making any changes to their interface or implementation.

This is ideal for long-running background workflows: you code can return at a later point and check the status for completion and/or retrieve the result.

var handle = DBOS.startWorkflow(()->example.exampleWorkflow("HelloDBOS"));
result = handle.getResult();

Read more ↗️

📒 Durable Queues

DBOS queues help you durably run distributed tasks. You can enqueue a task from a durable workflow and one of your processes will pick it up for execution. DBOS manages the execution of your tasks: it guarantees that tasks complete, and that their callers get their results without needing to resubmit them, even if your application is interrupted.

Queues also provide flow control, so you can limit the concurrency of your tasks on a per-queue or per-process basis. You can also set timeouts for tasks, rate limit how often queued tasks are executed, deduplicate tasks, or prioritize tasks.

You can add queues to your workflows in just a couple lines of code. They don't require a separate queueing service or message broker—just Postgres.

 public void queuedTasks() {
    for (int i = 0; i < 3; i++) {
        String workflowId = "child" + i;
        var options = new StartWorkflowOptions(workflowId).withQueue(q);
        List<WorkflowHandle<String>> handles = new ArrayList<>();
        handles.add(DBOS.startWorkflow(()->simpleService.childWorkflow(workflowId), options));
    }

    for (int i = 0 ; i < 3 ; i++) {
        String workflowId = "child"+i;
        var h = DBOS.retrieveWorkflow(workflowId);
        System.out.println(h.getResult());
    }
}

// In your main
var queue = new Queue("exampleQueue");
DBOS.registerQueue(queue);

Read more ↗️

📅 Durable Scheduling

Schedule workflows using cron syntax, or use durable sleep to pause workflows for as long as you like (even days or weeks) before executing.

You can schedule a workflow using a single annotation:

public class SchedulerImpl implements Scheduler {
    
    @Workflow(name = "every5Second")
    @Scheduled(cron = "0/5 * * * * ?")
    public void every5Second(Instant schedule , Instant actual) {
        log.info("Executed workflow  "+  schedule.toString() + "   " + actual.toString()) ;
    }
}

// In your main
DBOS.registerWorkflows(Scheduler.class, new SchedulerImpl());

Read more ↗️

📫 Durable Notifications

Pause your workflow executions until a notification is received, or emit events from your workflow to send progress updates to external clients. All notifications are stored in Postgres, so they can be sent and received with exactly-once semantics. Set durable timeouts when waiting for events, so you can wait for as long as you like (even days or weeks) through interruptions or restarts, then resume once a notification arrives or the timeout is reached.

For example, build a reliable billing workflow that durably waits for a notification from a payments service, processing it exactly-once:

@Workflow(name = "billing")
public void billingWorkflow() {
    // Calculate the charge, then submit the bill to a payments service
    String paymentStatus = (String) DBOS.recv(PAYMENT_STATUS, paymentServiceTimeout);
    if (paymentStatus.equals("paid")) {
        // handle paid
    } else {
        // handle not paid
    }
}

@Workflow(name = "payment") 
public void payment(String targetWorkflowId) {
    DBOS.send(targetWorkflowId, PAYMENT_STATUS, "paid") ;
}
      

To get started, follow the quickstart to install this open-source library and connect it to a Postgres database. Then, check out the programming guide to learn how to build with durable workflows and queues.

https://docs.dbos.dev

https://docs.dbos.dev/examples

DBOS vs. Temporal

Both DBOS and Temporal provide durable execution, but DBOS is implemented in a lightweight Postgres-backed library whereas Temporal is implemented in an externally orchestrated server.

You can add DBOS to your program by installing the open-source library, connecting it to Postgres, and annotating workflows and steps. By contrast, to add Temporal to your program, you must rearchitect your program to move your workflows and steps (activities) to a Temporal worker, configure a Temporal server to orchestrate those workflows, and access your workflows only through a Temporal client. This page makes the comparison in more detail.

If you want to ask questions or hang out with the community, join us on Discord! If you see a bug or have a feature request, don't hesitate to open an issue here on GitHub. If you're interested in contributing, check out our contributions guide.

联系我们 contact @ memedata.com