How to set Transaction Isolation level for a single kodo query?

243 views Asked by At

We have been facing deadlocks in some queries(select queries causing deadlocked update queries). By default kodo READS_COMMITTED,which is okay for update queries. I know that we can set this property at application level :

kodo.jdbc.TransactionIsolation: read-uncommitted

But in my case, I just want to specify the transaction isolation on a single kodo query. Is that possible? I am pretty new to kodo, so any help/comments any highly appreciated.

2

There are 2 answers

0
merryreaper On

What we end up doing in Kodo 3.4.0 is use CONN_RETAIN_PM (downcasting required):

try {
    pm = (KodoPersistenceManager)
        ((KodoPersistenceManagerFactory) kpmf).getPersistenceManager(false,
        KodoPersistenceManager.CONN_RETAIN_PM);
    Connection c = ((Connection)pm.getConnection());
    c.setTransactionIsolation(
        ISQLServerConnection.TRANSACTION_READ_UNCOMMITTED);

    // ... use pm with retained connection ...

} finally { // reset retained connection, e.g. if pooled
    if (pm != null) {
        Connection c = ((Connection)pm.getConnection());
        c.setTransactionIsolation(
            ISQLServerConnection.TRANSACTION_READ_UNCOMMITTED);
    }
}
0
Gatusko On

Using the documentation of Kodo with JDO:

Kodo provides explicit APIs to lock objects and to retrieve their current lock level. The Kodo JDO KodoPersistenceManager exposes the following methods to lock objects explicitly

You have the next methods of locking a object:

public void lockPersistent (Object pc);
public void lockPersistent (Object pc, int level, long timeout);
public void lockPersistentAll (Object[] pcs);
public void lockPersistentAll (Object[] pcs, int level, long timeout);
public void lockPersistentAll (Collection pcs);
public void lockPersistentAll (Collection pcs, int level, long timeout);

And the next example:

// retrieve the lock level of an object

Stock stock = ...;
int level = KodoJDOHelper.getLockLevel (stock);
if (level == KodoJDOHelper.LOCK_WRITE) 
        PersistenceManager pm = ...;
        pm.currentTransaction ().setOptimistic (true);
        pm.currentTransaction ().begin ();
        // override default of not locking during an opt trans to lock stock object
        KodoPersistenceManager kpm = KodoJDOHelper.cast (pm);
        kpm.lockPersistent (stock, KodoPersistenceManager.LOCK_WRITE, -1);
        stock.setPrice (market.calculatePrice (stock));
        pm.currentTransaction ().commit ();