2017-09-02 109 views
1

我试图想出一个处理事务锁及其恢复的解决方案。如何处理Java中的事务锁(Postgresql)

我有下面这样的代码:

try { 
    Connection conn = DriverManager.getConnection(url, userName, password); 
    Connection conn2 = DriverManager.getConnection(url, userName, password); 


    conn.setAutoCommit(false); 
    conn2.setAutoCommit(false); 

    conn.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ); 
    conn2.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ); 

    Statement stmt = conn.createStatement(); 
    Statement stmt2 = conn2.createStatement(); 

    stmt.setQueryTimeout(100); 
    stmt.executeUpdate("update layout set HEIGHT = 45 where ID = 2"); 
    stmt2.setQueryTimeout(10); 
    stmt2.executeUpdate("update layout set HEIGHT = 12 where ID = 2"); 
    conn2.commit(); 
    conn.commit(); 

    System.out.println("Done...."); 
} 

//TODO: should be throwing it back.. 
catch (Exception e) { 
    e.printStackTrace(); 
} 

现在我更新layout表中两个独立的交易。现在这会导致锁定,因此我使用setQueryTimeout重新覆盖了这种情况。

但我不确定setQueryTimeout是否是处理事务锁定和恢复的正确方法。还有其他的最佳做法吗?

请注意,我没有使用任何ORM的普通Java。

+0

很少理论,'悲观锁定'和'乐观锁定'是你知道的吗?总的来说很难说如何做'恢复',因为许多场景和许多要求都可以存在。这是企业软件中的重要问题之一 –

+0

想象一下银行或大型互联网商店,而你是客户。应该设计什么'交易恢复策略'? –

+0

@JacekCz:对不起,我不知道这一点。 – batman

回答

0

Dbms将使用锁。您可以通过乐观或悲观锁定,隔离级别,mvcc来增加或减少数量...... 最终锁定将被使用并可能导致死锁或长时间的等待期。我能想到的最合理的解决方案是超时。 重要的是,您如何从超时异常中恢复。

恢复应该是,该事务应该在超时后重试。通常这解决了大多数情况。为了确保你也可以处理案件是锁的原因停留较长时间,你应该决定有关:

  • 试之间的等待时间间隔,可能增加
  • 的最大数量
  • 的策略,如果系统无法解决问题该如何报警。