AnsweredAssumed Answered

With Spring integration, MyBatis closed db connection early

Question asked by xml2008 on Nov 27, 2010
Latest reply on Sep 8, 2015 by jbarrez
Hi,

I am trying to embed activiti (5.0rc1) engine in my web app with spring integration,
and doing something like following code:

public class UserBean {

  /** injected by Spring */
  private RuntimeService runtimeService;

  @Transactional
  public void hello() {
    // here you can do transactional stuff in your domain model
    // and it will be combined in the same transaction as
    // the startProcessInstanceByKey to the Activiti RuntimeService
    runtimeService.startProcessInstanceByKey("helloProcess");
  }
 
  public void setRuntimeService(RuntimeService runtimeService) {
    this.runtimeService = runtimeService;
  }
}

but MyBatis ManagedTransaction will always close the db connection before the Spring Transaction commits.


public class ManagedTransactionFactory implements TransactionFactory {

  private boolean closeConnection = true;

  public void setProperties(Properties props) {
    if (props != null) {
      String closeConnectionProperty = props.getProperty("closeConnection");
      if (closeConnectionProperty != null) {
        closeConnection = Boolean.valueOf(closeConnectionProperty);
      }
    }
  }

  public Transaction newTransaction(Connection conn, boolean autoCommit) {
    // Silently ignores autocommit, as managed transactions are entirely
    // controlled by an external manager.  It's silently ignored so that
    // code remains portable between managed and unmanaged configurations.
    return new ManagedTransaction(conn, closeConnection);
  }
}

DbSqlSessionFactory:


public void configurationCompleted(ProcessEngineConfiguration processEngineConfiguration) {
    this.databaseType = processEngineConfiguration.getDatabaseType();
    this.idGenerator = processEngineConfiguration.getIdGenerator();
    this.statementMappings = databaseSpecificStatements.get(processEngineConfiguration.getDatabaseType());

    DataSource dataSource = processEngineConfiguration.getDataSource();
    if (dataSource==null) { // standalone usage
      dataSource = createPooledDatasource(processEngineConfiguration);
    }
   
    TransactionFactory transactionFactory = null;
    if (processEngineConfiguration.isTransactionsExternallyManaged()) {
      transactionFactory = new ManagedTransactionFactory();
    } else {
      transactionFactory = new JdbcTransactionFactory();
    }
   
    this.sqlSessionFactory = createSessionFactory(dataSource, transactionFactory);
  }

Do I miss something to configure correctly?

Outcomes