关闭 DBI 是否处理从 postgres 数据库释放锁

Does closing DBI handle release lock from postgres database

我正在尝试编写一个 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();
        }
    }

DAOreturns余额,我运行检查余额看是否可以转账,然后调用另一个方法执行转账。

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 的新手。谢谢

它实际上是在 h.close() 之前的 h.commit() 发布的。行锁不会在提交后保持。

如果您需要在提交后保留的锁,您可以使用咨询锁,但它们有点笨拙,我不建议这样使用。

否则请继续阅读 pessimistic vs optimistic locking. See also Optimistic vs. Pessimistic locking