I want to make transactional update in two databases. Given I have following pseudocode:
try {
Connection conn1 = DriverManager.getConnection("jdbc:postgresql://HOST1", "postgres1", "password1"))
Connection conn2 = DriverManager.getConnection("jdbc:postgresql://HOST2", "postgres2", "password2"))
conn1.setAutoCommit(false);
conn2.setAutoCommit(false);
// insert
// update
conn1.commit();
conn2.commit();
} catch (Exception e) {
conn1.rollback();
conn2.rollback();
}
Will it work as intended?
If NO - why?
If YES - does it mean we don't need complex distributed transactions manager (such as based on XA protocol) for such cases?
Here is my understanding: the problem arises when conn1.commit() succeeds and conn2.commit() fails. If conn2.commit() method throws an Exception, we already have conn1 tx committed and conn1.rollback() will effectively do nothing, conn1 tx will stay there. We can mitigate this by adding code for reverting conn1 tx manually. In this case, apart from failure of that code - the modified approach should work. Apparently ACID guarantees are broken in this approach.