Home How does transaction propagation impact update in the database
Reply: 1

How does transaction propagation impact update in the database

Geek Published in 2018-01-13 05:03:02Z

I am trying to understand the behavior of transaction propagation using SpringJTA - JPA - Hibernate.

Essentially I am trying to update an entity. To do so I have written a test method where I fetch an object using entity manager (em) find method ( so now this object is manged object). Update the attributes of the fetched object. And then optionally make a call to service layer(service layer propagation=required) which is calling em.merge

Now I have three variations here :

  1. Test method has no transactional annotation. Update the attributes of the fetched object and make no call to service layer.

    1.1. Result level 1 cache doesn't gets updated and no update to DB.

  2. Test method has no transactional annotation. Update the attributes of the fetched object. Call the service layer.

    2.1. Result level 1 cache and DB gets updated.

  3. Test method has Transnational annotation which could be any of the following. Please see the table below for Propagation value at the test method and the outcome of a service call.

(service layer propagation=required)

So to read the above table, the row 1 says if the Test method has transaction propagation= REQUIRED and if a service layer call is made then the result is update to Level 1 cache but not to the DB

Below is my test case


    public void testUpdateCategory() {
//Get the object via entity manager
        Category rootAChild1 = categoryService.find(TestCaseConstants.CategoryConstant.rootAChild1PK);
        rootAChild1.setName(TestCaseConstants.CategoryConstant.rootAChild1 + "_updated");

// OPTIONALLY call update

//Get the object via entity manager. I believe this time object is fetched from L1 cache. As DB doesn't get updated but test case passes
Category rootAChild1Updated = categoryService.find(TestCaseConstants.CategoryConstant.rootAChild1PK);
        assertEquals(TestCaseConstants.CategoryConstant.rootAChild1 + "_updated", rootAChild1Updated.getName());
        List<Category> categories = rootAChild1Updated.getCategories();

Service Layer

    public class CategoryServiceImpl implements CategoryService {   
        public void update(Category category) {


    public class CategoryDaoImpl {
        public void update(Category category) {

Question Can someone please explain why does REQUIRED, REQUIRES_NEW, and NESTED doesn't lead to insertion in the DB?

And why absence of transaction annotation on Test case lead to insertion in the DB as presented in my three variations?


crizzis Reply to 2018-01-13 15:09:20Z

The effect you're seeing for REQUIRED, NESTED, and REQUIRES_NEW is due to the fact that you're checking for updates too early

(I'm assuming here that you check for db changes at the same moment when the test method reaches the assertions, or that you roll the test method transaction back somehow after executing the test)

Simply enough, your assertions are still within the context created by the @Transactional annotation in the test method. Consequently, the implicit flush to the db has not been invoked yet.

In the other three cases, the @Transactional annotation on the test method does not start a transaction for the service method to join. As a result, the transaction only spans the execution of the service method, and the flush occurs before your assertions are tested.

You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.300114 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO