我希望我的java代码的多个实例读取相同的数据集,并且我想锁定第一个实例读取的记录(行级别)。这样第二个实例就不会读取相同的数据。这是我的示例代码,它不起作用。如果我同时阅读两次,我会得到相同的记录。为了测试目的,我创建了列表1和列表2,并且一个接一个地读取两次以模拟读取相同数据的多个实例。
query = "SELECT * from xyz LIMIT 10 FOR UPDATE of xyz"
List<XYZ> list1= new ArrayList<XYZ>();
List<XYZ> list2= new ArrayList<XYZ>();
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setIsolationLevel(TransactionDefinition.ISOLATION_SERIALIZABLE);
TransactionStatus s=datasourceconfig.platformTransactionManager.getTransaction(def);
try {
list1= datasourceconfig.queryForObjectList(query , paramMap ,XYZ.class);
} catch (Exception ex) {
log.error("", ex);
}
try {
list2= datasourceconfig.queryForObjectList(query,paramMap,XYZ.class);
} catch (Exception ex) {
log.error("", ex);
}
empDsCfg.platformTransactionManager.commit(s);
当我得到结果时,两个列表都有相同的记录。请帮助。
答案 0 :(得分:0)
如果您使用的是PostgreSQL 9.5或更高版本,则可以使用
SELECT ...
LIMIT 10
FOR UPDATE SKIP LOCKED;
将选择并锁定最多十个尚未被并发事务锁定的行。
可以与所有PostgreSQL版本一起使用的替代方法是使用这样的咨询锁:
SELECT ...
WHERE pg_try_advisory_xact_lock(id)
LIMIT 10
FOR UPDATE;
这里id
是主键,并且假设它是一个整数值(可以隐式地转换为bigint
的类型)。
如果没有包含该号码的独占advisory lock,此函数将返回TRUE
,并将锁定作为副作用。
注意:锁仅在事务持续期间保持,因此请务必在单个事务中执行锁定和后续数据修改。