Naruto Naruto - 2 months ago 8
Java Question

Handling concurrency in Java using Spring Hibernate

In Hibernate, there are options to manage hibernate and i have tried all most all the isolation levels on query along with locks but still i can see dirty read in my code.

So i have tried following things,

class A {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
int id;


...

//setter and getter
}


Another object

class B {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name="bid")
int bid;

...
@ManyToOne(fetch = FetchType.EAGER )
@JoinColumn(name = "id")
private A a;

@Column(name="value")
int value
//setter and getter
}

class E {
//POJO having ManyToOne relation on class A + extra fields

//setter and getter
}


Now i have tried all 4 isolation level, REPEATABLE READ
| READ COMMITTED
| READ UNCOMMITTED
| SERIALIZABLE as specified in http://dev.mysql.com/doc/refman/5.7/en/set-transaction.html but still i can see dirty read on the table.

So how i am using this is,

class C {
@Autowired
private EntityManager entityManager;

public B getB(A a){
TypedQuery<B> query = entityManager.createNamedQuery("A.getB",B.class);
query.setParameter("a",a);
query.setLockMode(LockModeType.PESSIMISTIC_WRITE) //I have tried almost every type of lock here ranging from OPTIMISTIC_LOCK,OPTIMISTIC_FORCE_INCREMENT, PESSIMISTIC_READ, PESSIMISTIC_WRITE but even i can see dirty read
B b = query.getSingleResult();
return b;
}
}


class D {
@Autowired
private C c;
@Transactional(isolation = Isolation.SERIALIZABLE)
private B getB(A a) {
//Multiple DB calls within transaction here.

B b = c.getB(a);
b.setValue(b+10);
b.merge();
}
}


So using Serializable, i can see it working but many calls are failed saying ROLLBACK DUE TO DEADLOCK, when there are concurrent calls.

But when i change isolation level or lockmode, its not working , i can see dirty read in this.

I checked locks using

SHOW OPEN TABLES from DB_NAME


this gives me all the locks/threads waiting for locks. Can anyone help me to prevent from deadlock or from dirty read.

Answer

Thanks Vlad. I actually used

entitymanager.refresh(object,LockModeType.PESSIMISTIC_WRITE)

which actually hepled me to get everytime the latest value from database with write lock hence solved the problem.