Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring @Transactional Timeout not working as expected

I have a JDBC batch update operation which might take long time, hence I am using transaction timeout to handle this.

@Override
@Transactional(propagation=Propagation.REQUIRES_NEW,timeout=10)
public void saveAllUsingBatch(List<KillPrintModel> list){
    PreparedStatmentMapper ps=  new HibernateDao.PreparedStatmentMapper<KillPrintModel>() {

        @Override
        public void prepareStatement(PreparedStatement ps, KillPrintModel t)
                throws SQLException {
            ps.setString(1, t.getOffice());
            ps.setString(2, t.getAccount());
            ps.setDate(3, new java.sql.Date(t.getUpdatedOn().getTime()));
        }
    };
    String sql = String.format("INSERT INTO dbo.%s (%s,%s,%s) VALUES (?,?,?)",KillPrintModel.TABLE_NAME,KillPrintModel.FIELD_Office,KillPrintModel.FIELD_Account,KillPrintModel.FIELD_UpdatedOn);
    this.jdbcBatchOperation(list, sql, ps);
}

This method goes on for more than a minute(and returns successfully) even when I have a transaction time out of 10 seconds. It works fine when the timeout is 0.


Is it because My thread is always in running state once it starts execution ?

like image 259
Rahul Avatar asked Aug 07 '15 11:08

Rahul


People also ask

How do I increase transaction timeout in spring boot?

You can use property: spring. transaction. default-timeout= # Default transaction timeout in seconds.

How do I set transaction timeout in Spring?

For any transaction, we can provide a transaction timeout using @Transactinal annotation. When we define @Transactional(timeout = 100) then we are saying our transaction should complete in given time frame otherwise we will get TransactionException(transaction time expired error).

Does @transactional close session?

@Transactional helps you to extend scope of Session . Session is open first time when getCurrentSession() is executed and it is closed when transaction ends and it is flushed before transaction commits.

What are the default @transactional settings?

The default @Transactional settings are: The propagation setting is PROPAGATION_REQUIRED. The isolation level is ISOLATION_DEFAULT. The transaction is read/write.


1 Answers

If debugging in trace mode does not help, just put a breakpoint in the following hibernate classes, they ultimately set a timeout in the preparedstatement.setQueryTimeout(...) from the @Transactional Annotation

org.hibernate.engine.jdbc.internal.StatementPreparerImpl
private void setStatementTimeout(PreparedStatement preparedStatement) throws SQLException {
            final int remainingTransactionTimeOutPeriod = jdbcCoordinator.determineRemainingTransactionTimeOutPeriod();
            if ( remainingTransactionTimeOutPeriod > 0 ) {
                preparedStatement.setQueryTimeout( remainingTransactionTimeOutPeriod );
            }
        }

Or even better, as early as the transaction manager and step through until you hit the statement.setQueryTimout(..).

org.springframework.orm.hibernate4.HibernateTransactionManager
int timeout = determineTimeout(definition);
            if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {
                // Use Hibernate's own transaction timeout mechanism on Hibernate 3.1+
                // Applies to all statements, also to inserts, updates and deletes!
                hibTx = session.getTransaction();
                hibTx.setTimeout(timeout);
                hibTx.begin();
            }
            else {
                // Open a plain Hibernate transaction without specified timeout.
                hibTx = session.beginTransaction();
            }
like image 177
kisna Avatar answered Sep 29 '22 20:09

kisna