1   /*
2    * $Id: TransactionTemplateTestCase.java 7976 2007-08-21 14:26:13Z dirk.olmes $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSource, Inc.  All rights reserved.  http://www.mulesource.com
5    *
6    * The software in this package is published under the terms of the CPAL v1.0
7    * license, a copy of which has been included with this distribution in the
8    * LICENSE.txt file.
9    */
10  
11  package org.mule.transaction;
12  
13  import org.mule.MuleManager;
14  import org.mule.impl.DefaultExceptionStrategy;
15  import org.mule.impl.MuleTransactionConfig;
16  import org.mule.tck.AbstractMuleTestCase;
17  import org.mule.umo.UMOTransaction;
18  import org.mule.umo.UMOTransactionConfig;
19  
20  import com.mockobjects.dynamic.Mock;
21  
22  import javax.transaction.Transaction;
23  import javax.transaction.TransactionManager;
24  
25  /**
26   * http://mule.mulesource.org/jira/browse/MULE-1494
27   */
28  public class TransactionTemplateTestCase extends AbstractMuleTestCase
29  {
30      protected Mock mockTm = new Mock(TransactionManager.class);
31  
32      protected void doSetUp() throws Exception
33      {
34          TransactionManager tm = (TransactionManager) mockTm.proxy();
35          MuleManager.getInstance().setTransactionManager(tm);
36      }
37  
38      public void testNoNestedTxStarted() throws Exception
39      {
40          Mock mockTx = new Mock(Transaction.class);
41          mockTm.expect("begin");
42          mockTm.expectAndReturn("getTransaction", mockTx.proxy());
43          // anything which is not rolled/ing back is fine
44          mockTx.expectAndReturn("getStatus", UMOTransaction.STATUS_ACTIVE);
45  
46          // and the final commit expectations
47          mockTx.expectAndReturn("getStatus", UMOTransaction.STATUS_ACTIVE);
48          mockTx.expect("commit");
49  
50          // this is one component with a TX always begin
51          UMOTransactionConfig config = new MuleTransactionConfig();
52          config.setFactory(new XaTransactionFactory());
53          config.setAction(UMOTransactionConfig.ACTION_ALWAYS_BEGIN);
54          TransactionTemplate template = new TransactionTemplate(config, new DefaultExceptionStrategy());
55  
56          // and the callee component which should join the current XA transaction, not begin a nested one
57          final UMOTransactionConfig nestedConfig = new MuleTransactionConfig();
58          nestedConfig.setFactory(new XaTransactionFactory());
59          nestedConfig.setAction(UMOTransactionConfig.ACTION_BEGIN_OR_JOIN);
60  
61          // start the call chain
62          template.execute(new TransactionCallback()
63          {
64              public Object doInTransaction() throws Exception
65              {
66                  // the callee executes within its own TX template, but uses the same global XA transaction,
67                  // bound to the current thread of execution via a ThreadLocal
68                  TransactionTemplate nestedTemplate =
69                          new TransactionTemplate(nestedConfig, new DefaultExceptionStrategy());
70                  return nestedTemplate.execute(new TransactionCallback()
71                  {
72                      public Object doInTransaction() throws Exception
73                      {
74                          // do not care about the return really
75                          return null;
76                      }
77                  });
78              }
79          });
80  
81          // nobody leaves until checked ;)
82          mockTm.verify();
83          mockTx.verify();
84      }
85  
86  }