关闭DBI句柄是否释放Postgres数据库中的锁?

3

我正在尝试编写一个 Web 应用程序,它将在多个服务器上运行,但共享单个财务交易数据库。

简单来说,我想从账户 A 转账到 B。但可能会有多个请求从同一账户转账。

余额永远不能为负数,因此我决定使用 SELECT FOR UPDATE 获取余额并锁定行。

我正在使用 JDBI 连接到数据库:http://jdbi.org/

代码流程如下:

控制器:

DBI dbi = new DBI(datasource);

.....
getAccountBalance();

....

transfer()

这里是 DOA 部分。

public int getAccountBalance(String id) {
        Handle h = dbi.open();
        try{
            return h.createQuery("SELECT balance FROM accounts " +
                                " WHERE id=:id FOR UPDATE;")
                    .bind("id", id)
                    .mapTo(Integer.class)
                    .first();
        } finally {
            h.close();
        }
    }

The DAO(去中心化自治组织)返回余额,我进行余额检查以确定是否可以进行转账,然后调用另一个方法来执行转账。

public void transfer(String fromAccountId, String toAccountId, int transferAmount) {
        Handle h  = dbi.open();
        try{
            h.begin();
            h.createStatement("UPDATE accounts SET balance = balance - :transferAmount WHERE id = :fromAccountId")
                .bind("fromAccountId", fromAccountId)
                .bind("transferAmount", transferAmount)
                .execute();
            h.createStatement("UPDATE accounts SET balance = balance + :transferAmount WHERE id = :toAccountId")
                .bind("toAccountId", toAccountId)
                .bind("transferAmount", transferAmount)
                .execute();
            h.commit();
        } finally {
            h.close();
        }
    }

我的问题是,如果我在getAccountBalance()中关闭句柄,它会释放所选行上的锁吗?如果是这种情况,我该如何保持锁定状态?我对DBI还不熟悉。谢谢。

1个回答

3

这实际上是在 h.commit() 之前发布的,而不是在 h.close() 之前。行锁定不会超出提交。

如果您需要在提交后保持锁定,则可以使用咨询锁定,但它们有点棘手,对于这样的事情我不建议使用。

否则,请阅读乐观锁定与悲观锁定。另请参阅乐观锁定与悲观锁定


我在A方法中创建了锁,但是在B方法中提交。这样还能保持锁定吗?如果我之前没有解释清楚,对不起。 - Amit Vig
所以 瞎猜一下getAccountBalance 没有启动显式事务,因此它是自动提交的。因此,在语句返回后,锁定不会保持。但这是对您的事务边界做出一些猜测。 - Craig Ringer
@AmitVig 所以你需要在jdbi中查找事务管理。 - Craig Ringer
我已经找到了一种使用@Transaction注解的方法。这个注解可以让我在一个事务中运行整个SQL集合,并得到我想要的结果。谢谢。 - Amit Vig
@AmitVig 考虑使用 JDBI 具体说明并编写您自己的答案。 - Craig Ringer
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接