admin管理员组

文章数量:1200978

I have code like this:

@Transactional
@RestController
public class TestController {

    @Transactional(propagate = NEVER)
    public void testTransactionLeak(){
        repository.findAll();
        Thread.sleep(40_000);
    }

    public void otherCrudEndpoint(){
        repository.doSomething();
    }
}

When calling the testTransactionLeak() method, hikariCP is complaining about a connection leak after 30 seconds. I dont understand this as i would have expected that propagate = NEVER is telling spring to not create a transaction in this case and this would mean there is nothing to leak.

PS: If i remove all the transactional annotations, it works as expected, but I prefer to have an @Transactional annotation on the controller as i want to have the behaviour that any error will rollback all the database changes (CRUD app) and i dont want that devs forget to set the annoation themselves

I have code like this:

@Transactional
@RestController
public class TestController {

    @Transactional(propagate = NEVER)
    public void testTransactionLeak(){
        repository.findAll();
        Thread.sleep(40_000);
    }

    public void otherCrudEndpoint(){
        repository.doSomething();
    }
}

When calling the testTransactionLeak() method, hikariCP is complaining about a connection leak after 30 seconds. I dont understand this as i would have expected that propagate = NEVER is telling spring to not create a transaction in this case and this would mean there is nothing to leak.

PS: If i remove all the transactional annotations, it works as expected, but I prefer to have an @Transactional annotation on the controller as i want to have the behaviour that any error will rollback all the database changes (CRUD app) and i dont want that devs forget to set the annoation themselves

Share Improve this question asked Jan 22 at 10:07 KP_EVKP_EV 33 bronze badges 3
  • Two things. 1) it looks like a bug - somehow the class level annotation is causing a transaction to be initiated behind the proxy so that it is not picked up by the propagate NEVER, 2) propagate NEVER should throw an exception when called within an existing transaction, not prevent one from being initialised. Following the question to see if there is a better explanation. – John Williams Commented Jan 22 at 11:50
  • Using JPA by any chance? Disabled the spring.jpa.open-in-view=false as that would quite eagerly open a connection before anything else. – M. Deinum Commented Jan 22 at 12:37
  • We are using jpa and we have open-in-view already disabled – KP_EV Commented Jan 22 at 12:52
Add a comment  | 

1 Answer 1

Reset to default 0

Based on this article: https://medium.com/@dulanjayasandaruwan1998/understanding-transactional-propagation-in-spring-boot-ec958521794d

Also based on the spring documentation, this method should always throw an exception if there is currently a transaction executing.

Assuming you have open-in-view=false for spring.jpa in your properties, you probably want NOT_SUPPORTED instead of NEVER

NOT_SUPPORTED executes the method without a transaction. If a transaction is present, it will be suspended during the method execution.

Use NOT_SUPPORTED when you want to ensure that a method does not run within a transaction context, such as for non-transactional operations like reading configuration data .

本文标签: hibernatepropagateNEVER still creates a transaction in springStack Overflow