1 Reply Latest reply on Oct 17, 2007 4:17 PM by jfrankman

    How to avoid transaction Timeouts for long running MDB

      If I have a single SLSB with method A and Method B which are called sequentially (first A then B) by a MDB how do I keep Method B from getting a transaction timeout error when method A takes a very long time to complete?

      I have a MDB which firsts downloads some files from a FTP site and processes the files. The download can take several minutes depending upon the size of the file and the network speed. Once the download is complete I use hibernate to read the contents of the text file downloaded from the FTP site. The problem I am having is that after 5 minutes or so while the file is still downloading I get:

      16:55:48,266 WARN [TransactionImpl] Transaction TransactionImpl:XidImpl[FormatId=257, GlobalId=fbmis011/19, BranchQual=, localId=19] timed out. status=STATUS_ACTIVE

      At first I tried to up the timeout limit, by using

      "@TransactionTimeout(1800)" on the MDB. However, this is a poor workaround since a download could take a very long time depending upon the size of the file. What I would like to do is not have the transaction begin until after the download has completed. Both the download and the hibernate query happen in the same SLSB. Despite my efforts, I still get a transaction time out error in the method that uses hibernate to query the file (getIndexFileDetailRecords()). Here is my code in its current state:

      MDB:

      @MessageDriven(activationConfig =
      {
       @ActivationConfigProperty(propertyName="destinationType",
       propertyValue="javax.jms.Queue"),
       @ActivationConfigProperty(propertyName="destination",
       propertyValue="queue/KeyBankCheckImageQueue")
      })
      
      
      @Name("keybankCheckImagesMessageHandler")
      public class KeyBankCheckImagesMessageHandler implements MessageListener{
      
       @In(create=true) KeyBankServices keybankServices;
      
       public void onMessage (Message msg) {
      
       MapMessage mapMessage=(MapMessage)msg;
       try {
       System.out.println("process checks.");
       //mapMessage.getInt("lower");
       InitialContext ctx = new InitialContext();
       //JNDI tests. I settled with using the jboss-services.xml, but the SystemPropertiesService could have been used.
       //String text = (String) ctx.lookup("keybankchecks/path");
       //SystemPropertiesService abc = new SystemPropertiesService();
       //text=abc.get("aaa");
      
       try {
       //keySrv.cleanRemoteBackups();
       keybankServices.cleanRemoteBackups();
       } catch (Exception e) {
       e.printStackTrace();
       }
       keybankServices.downloadKeyBankFiles();
       keybankServices.processKeyBankFiles();
       }
       catch (NamingException e) {
      
       e.printStackTrace();
       }
       }
      
      }


      Here is the SLSB with the method that times out (getIndexFileDetailRecords()).

      @Stateless
      @Name("keybankServices")
      public class KeyBankServicesImpl implements KeyBankServices
      {
      
       @PersistenceContext()
       private EntityManager em;
      
       private KeyBankConfiguration keyBankConfig;
       //private File batchDirectory;
       private static Logger logger;
       //@org.jboss.seam.annotations.Logger
       //private Log logger;
      
       private static final String DOWNLOADING="downloading_";
      
      
      
       public KeyBankServicesImpl()
       {
       init();
      
       }
      
       //@Create
       public void init()
       {
       System.setProperty("line.separator", "\r\n");
      
       //enable logger
       logger=Logger.getLogger(KeyBankServicesImpl.class.getName());
       logger.info("KeyBankServicesImpl class instantiated.");
      
      
       try {
       keyBankConfig=new KeyBankConfiguration();
       } catch (NamingException e) {
       logger.error(e.getStackTrace());
       //e.printStackTrace();
       }
       logger.info("KeyBankServicesImpl configuration:" + keyBankConfig);
       cleanupBackups();
      
       }
      
       @Begin(join=true)
       @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
       public void downloadKeyBankFiles()
       {
       ...stuff.
      
       }
      
       @Begin(join=true)
       @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
       public void processKeyBankFiles()
       {
       stuff....
       }
      
       @Begin(join=true)
       @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
       private Collection<IndexDetail> getIndexFileDetailRecords()
       {
       Collection<IndexDetail> returnCollection;
       String query = "from IndexDetail";
       Query hqlQuery =em.createQuery(query);
       returnCollection =hqlQuery.getResultList();
       return returnCollection;
       }


      Any help would be appreciated.

      Thanks


        • 1. Re: How to avoid transaction Timeouts for long running MDB

          I found that the best way to do this was to place the @TransactionAttribute on the class instead of the method. I did not realize this annotation could work on either a method or class.

          @Stateless
          @Name("keybankServices")
          @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
          public class KeyBankServicesImpl implements KeyBankServices
          {