`@Transactional void placeOrder(Order o) { save(o); notify(o); }` calls `private void notify(Order o) { ... }` on the same class, and `notify` is also annotated `@Transactional(propagation = REQUIRES_NEW)` — the intent being "notify commits in its own transaction, independent of placeOrder's." It doesn't. Why not, precisely, and would making `notify` public fix it?
A Spring @Transactional bean is wrapped in a proxy, and the proxy is the object that actually intercepts calls and opens/closes transactions — but a proxy only intercepts calls that arrive through it from the outside. this.notify(o) called from inside placeOrder never goes through the proxy at all: this inside a bean is the real, un-proxied target object, so the call is an ordinary Java method call straight to notify's body, and the @Transactional(REQUIRES_NEW) annotation on it is simply never consulted by anything — it might as well not be there. And no, making notify public doesn't fix it, for a separate reason stacked on top: the problem isn't that notify can't be reached from outside, it's that this particular call to it, this.notify(o), never leaves the object to reach the proxy in the first place. The fix has to change how the call is made — through the proxy, not around it — not the visibility of the method being called.