我们在一些查询中遇到了死锁(选择查询导致死锁更新查询)。默认情况下 kodo READS_COMMITTED,这对于更新查询是可以的。我知道我们可以在应用程序级别设置此属性:
kodo.jdbc.TransactionIsolation: read-uncommitted
但就我而言,我只想在单个 kodo 查询上指定事务隔离。那可能吗?我对科多很陌生,所以任何帮助/评论都非常感谢。
将 Kodo 的文档与 JDO 一起使用:
Kodo 提供了明确的 API 来锁定对象并检索它们当前的锁定级别。Kodo JDO KodoPersistenceManager 公开了以下方法来显式锁定对象
您有以下锁定对象的方法:
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);
下一个例子:
// 获取对象的锁级别
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 ();
我们最终在 Kodo 3.4.0 中做的是使用 CONN_RETAIN_PM(需要向下转换):
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);
}
}