4

I am having some issues regarding transactions. I am not using JTA.

It is possible that I am starting a new transaction while already in a transaction, eventually causing this exception:

java.lang.Thread.run(Thread.java:745)
    org.postgresql.util.PSQLException: The connection attempt failed.
    org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:233)
    org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:64)
    org.postgresql.jdbc2.AbstractJdbc2Connection.<init>(AbstractJdbc2Connection.java:144)
    org.postgresql.jdbc3.AbstractJdbc3Connection.<init>(AbstractJdbc3Connection.java:29)
    org.postgresql.jdbc3g.AbstractJdbc3gConnection.<init>(AbstractJdbc3gConnection.java:21)
    org.postgresql.jdbc4.AbstractJdbc4Connection.<init>(AbstractJdbc4Connection.java:31)

java.lang.Thread.run(Thread.java:745)
    java.net.NoRouteToHostException: Cannot assign requested address
    java.net.PlainSocketImpl.socketConnect(Native Method)
    java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:345)
    java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
    java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
    java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
    java.net.Socket.connect(Socket.java:589)
    org.postgresql.core.PGStream.<init>(PGStream.java:61)
    org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:109)
    org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:64)
    org.postgresql.jdbc2.AbstractJdbc2Connection.<init>(AbstractJdbc2Connection.java:144)
    org.postgresql.jdbc3.AbstractJdbc3Connection.<init>(AbstractJdbc3Connection.java:29)
    org.postgresql.jdbc3g.AbstractJdbc3gConnection.<init>(AbstractJdbc3gConnection.java:21)
    org.postgresql.jdbc4.AbstractJdbc4Connection.<init>(AbstractJdbc4Connection.java:31)
    org.postgresql.jdbc4.Jdbc4Connection.<init>(Jdbc4Connection.java:24)
    org.postgresql.Driver.makeConnection(Driver.java:410)
    org.postgresql.Driver.connect(Driver.java:280)
    java.sql.DriverManager.getConnection(DriverManager.java:664)
    java.sql.DriverManager.getConnection(DriverManager.java:208)

I read here that when JTA is not used, the way it suspends and creates a new transaction is by creating a new connection, possibly explaining the exception above.

How does transaction suspension work in Spring?

My code should be creating and comitting the transaction before a new one is created, however I am uncertain.

I have 8 threads populating data, with each thread in a loop creating a new transaction, working, comitting, over and over again.

How can I figure out if I am in a "nested" mode with regards to the transactions?

TransactionSynchronizationManager only provides info if there is a current transaction, not how many are suspended under the same thread to figure out if there is a problem here.

I would also be interested in knowing how many current transactions are in progress globally, across all threads if possible.

Community
  • 1
  • 1
mjs
  • 21,431
  • 31
  • 118
  • 200

1 Answers1

2

When the propagation setting is PROPAGATION_REQUIRED, a logical transaction scope is created for each method upon which the setting is applied. Each such logical transaction scope can determine rollback-only status individually, with an outer transaction scope being logically independent from the inner transaction scope. Of course, in case of standard PROPAGATION_REQUIRED behavior, all these scopes will be mapped to the same physical transaction.

For more details refer this link.

Community
  • 1
  • 1
Harshal Patil
  • 6,659
  • 8
  • 41
  • 57
  • I thought that PROPAGATION_REQUIRED would join an existing transaction, causing a rollback on all of the transaction in case of an error in subsequent PROPAGATION_REQUIRED methods. I am kind of surprised by this statement. How sure are you? :) – mjs Dec 16 '14 at 16:00
  • It joins transactions, but apply timeout, comminOn/rollbackOn individually based on `@Transactional(...)` settings, per method. – gavenkoa Jan 17 '20 at 20:22