سؤال

I am trying to update a Company object in a new transaction and expecting the same object to be retrieved having updated parameters. But they are not :( Name does not change. 'after' and 'before' are the same. Database was updated but the outer transaction doesn't know about this. Do you know any workarounds for such a case?

  @Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = false)
    public Status newTransactionTest() {
    logger.info("newTransactionTest() INNER");
    Company company = companyDAO.findOne(10000013);
    company.setName(company.getName() + "X");

    return Status.OK;
  }

  @Transactional(propagation = Propagation.REQUIRED, readOnly = false)
  public Status test() {
    logger.info("test() BEFORE");
    Company company1 = companyDAO.findOne(10000013);
    String before = company1.getName();

    // run in a new transaction
    applicationContext.getBean(beanName, AdminService.class).newTransactionTest();

    logger.info("test() AFTER");
    Company company2 = companyDAO.findOne(10000013);
    String after = company2.getName();

    logger.info("COMPANY NAME BEFORE: " + before);

    logger.info("COMPANY NAME AFTER: " + after);

    return Status.OK;
  }

and the logs are:

test() BEFORE
connection: 122 select company0_.name as name7_4_0_ ... where company0_.id=5000062
newTransactionTest() INNER
connection: 123 select company0_.name as name7_4_0_ ... where company0_.id=5000062
connection: 123 update Company set name='TestorexX' where id=5000062
connection: 123 commit
test() AFTER
connection: 122 select company0_.name as name7_4_0_ ... where company0_.id=5000062
COMPANY NAME BEFORE: Testorex
COMPANY NAME AFTER: Testorex
هل كانت مفيدة؟

المحلول

Ok, finally I have fixed this bug. The problem was with a default isolation level which was on my local mySQL instance and Cloud SQL set to REPEATABLE-READ. To check these settings I used:

SHOW VARIABLES WHERE Variable_name ='tx_isolation'

so my repeated queries returned the same result because of cashing done on the db level not as I expected on hibernate/spring

To change REPEATABLE-READ to READ COMMITTED I added this to my persistence.xml

<property name="hibernate.connection.isolation">2</property>

Where

1: READ UNCOMMITTED
2: READ COMMITTED
4: REPEATABLE READ
8: SERIALIZABLE

Now everything works fine as it is expected. In the beginning of every new transaction hibernate does

SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED

The outer transaction sees changes from the inner!

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top