Hacker Newsnew | past | comments | ask | show | jobs | submit | gunnarmorling's commentslogin

> No they are not common at all. You probably invented them just to make pg look bad.

Interactive transactions are a well-defined concept in database technology, exactly with the semantics described by the author: transactions with multiple queries, with application logic in between, for instance taking a result from one query, processing it, and running a second query with the outcome of that processing as input.

That said, the example in the blog post feels a bit contrived to me, the question being whether that transaction could be structured in a why so that both updates run right after each other towards the end of the transaction, thus significantly reducing the duration of the row lock being held (which is not to say that the general problem described in the article doesn't exist, it does for sure).


I wanted the example to be simple and relatable. So I went with something close to the transaction example on the Postgres site (which to be honest also feels contrived).

In practice I'd never implement a ledger like this these days, I'd much prefer an append only model with some triggers. But, like you said interactive transactions are very much a thing.

Out of curiosity do you have a better/less contrived example in mind?


You could do that, but you'd run into exactly the same bottleneck the author describes with a remote Postgres instance. The workload exposes high contention on hot rows. If transactions are kept open for several milliseconds due to this being a remote network call between client and DB server, throughput will be equally limited also when using SQLite.

Yeah this is a very good point. Any sort of network drive will have similar issues with SQLite. You're very much wanting attached NVME.

The comment at [1] hints at a solution: in the response of the write request return the id of the transaction or its commit position in the TX log (LSN). When routing a subsequent read request to a replica, the system can either wait until the transaction is present on the replica, or it redirect to to the primary node. Discussed a similar solution a while ago in a talk [2], in the context of serving denormalized data views from a cache.

[1] https://news.ycombinator.com/item?id=46073630 [2] https://speakerdeck.com/gunnarmorling/keep-your-cache-always...


ProxySQL has a more simplified version of this, but it’s transparent to the client. Since it’s constantly monitoring the cluster, it knows what replica lag is at any given time. If you send a request to a read replica, it holds the request until enough time has passed for the replica to have caught up.

Great to see more love for using Lucene on Lambda via GraalVM native binaries! Explored that same idea few years back for my personal blog [1]. It worked pretty well, but I moved eventually away from Lambda as I wanted to close down my personal AWS account. One thing I always meant to explore was embedding the (in my case small) Lucene index directly into the binary image using Lucene's RAMDirectory via Quarkus' bytecode recording machinery, but I never got to it.

[1] https://www.morling.dev/blog/how-i-built-a-serverless-search...


It depends on what exactly you mean by "Atomic Transaction". If you are referring to database transactions, then DE is not that. But DE helps you implement potentially long-running multi-step business transactions, a.k.a. workflows, sometimes spanning over days or weeks. Oftentimes, these transactions are atomic, but don't satisfy the isolation requirement of ACID transactions, i.e. partial outcomes of in-flight flows may be visible to external observers.

Sure, systems like Activiti or Camunda come to mind.

my question is does anyone (here on HN is implied) really do this? in production for some serious purpose?

I worked on a product that used BPMN where users could define processes. The company I worked for used Java for decades already. Clients of the product were banks.

The people I worked with were not specifically HN audience. Rather in the Java bubble in Germany-Austria-Switzerland which is also surprisingly a small world. If BPMN is not really needed, then I would also not use it nowadays. It increases complexity, and who knows if it makes project communication better at all.

Update: On the Camunda website there are 60 case-studies of customers/clients using BPMN, https://camunda.com/case-studies/. One of them has the teaser: "The 10th largest US Bank created an omnichannel onboarding platform that handles 12m process instances per year across 100 workflows". Now I have something to read for this Sunday evening.


Thanks. I guess I'm in my bubble...

Camunda (not affiliated btw.) crossed 100M ARR last year. So yes, this apparently is being used. Whether these users hang out here on HN or not, that I don't know.

Ah, that's awesome. Definitely need to take a closer look at your implementation.

I'm still swinging back and forth which approach I ultimately prefer.

As stated in the post, I like how the proxy approach largely avoids any API dependency. I'd also argue that Java developers actually are very familiar with this kind of implicit enrichment of behaviors and execution semantics (e.g. transaction management is weaved into applications that way in Spring or Quarkus applications).

But there's also limits to this in regards to flexibility. For example, if you wanted to delay a method for a dynamically determined period of time, rather than for a fixed time, the annotation-based approach would fall short.


At Temporal, for Java we did a hybrid approach of what you have. Specifically, we do the java.lang.reflect.Proxy approach, but the user has to make a call instantiating it from the implementation. This allows users to provide those options at proxy creation time and not require they configure a build step. I can't speak for all JVM people, but I get nervous if I have to use a library that requires an agent or annotation processor.

Also, since Temporal activity invocations are (often) remote, many times a user may only have the definition/contract of the "step" (aka activity in Temporal parlance) without a body. Finally, many times users _start_ the "step", not just _execute_ it, which means it needs to return a promise/future/task. Sure this can be wrapped in a suspended virtual thread, but it makes reasoning about things like cancellation harder, and from a client-not-workflow POV, it makes it harder to reattach to an invocation in a type-safe way to, say, wait for the result of something started elsewhere.

We did the same proxying approach for TypeScript, but we saw as we got to Python, .NET, and Ruby that being able to _reference_ a "step" while also providing options and having many overloads/approaches of invoking that step has benefits.


Yupp, making that same point in the post :)

> You could think of [Durable Execution] as a persistent implementation of the memoization pattern, or a persistent form of continuations.


> I never understood why AOT never took off for Java.

GraalVM native images certainly are being adopted, the creation of native binaries via GraalVM is seamlessly integrated into stacks like Quarkus or Spring Boot. One small example would be kcctl, a CLI client for Kafka Connect (https://github.com/kcctl/kcctl/). I guess it boils down to the question of what constitutes "taking off" for you?

But it's also not that native images are unambiguously superior to running on the JVM. Build times definitely leave to be desired, not all 3rd party libraries can easily be used, not all GCs are supported, the closed world assumption is not always practical, peak performance may also be better with JIT. So the way I see it, AOT compiled apps are seen as a tactical tool by the Java community currently, utilized when their advantages (e.g. fast start-up) matter.

That said, interesting work is happening in OpenJDK's Project Leyden, which aims to move more work to AOT while being less disruptive to the development experience than GraalVM native binaries. Arguably, if you're using CDS, you are using AOT.


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: