选择更新不使用jdbc模板(posgres)

时间:2017-03-17 12:14:19

标签: java postgresql asynchronous locking jdbctemplate

我希望我的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);

当我得到结果时,两个列表都有相同的记录。请帮助。

1 个答案:

答案 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,并将锁定作为副作用。

注意:锁仅在事务持续期间保持,因此请务必在单个事务中执行锁定和后续数据修改。