~ubuntu-branches/ubuntu/natty/eucalyptus/natty-updates

« back to all changes in this revision

Viewing changes to clc/modules/msgs/src/main/java/com/eucalyptus/util/TxHandle.java

  • Committer: Bazaar Package Importer
  • Author(s): Dustin Kirkland
  • Date: 2009-12-17 18:22:02 UTC
  • mto: This revision was merged to the branch mainline in revision 83.
  • Revision ID: james.westby@ubuntu.com-20091217182202-0v2v09ry3cxrvh84
Tags: upstream-1.6.2~bzr1103
ImportĀ upstreamĀ versionĀ 1.6.2~bzr1103

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
package com.eucalyptus.util;
2
 
 
3
 
import java.lang.ref.WeakReference;
4
 
import java.util.Calendar;
5
 
import java.util.UUID;
6
 
import java.util.concurrent.ConcurrentNavigableMap;
7
 
import java.util.concurrent.ConcurrentSkipListMap;
8
 
 
9
 
import javax.persistence.EntityManager;
10
 
import javax.persistence.EntityManagerFactory;
11
 
import javax.persistence.EntityTransaction;
12
 
 
13
 
import org.apache.commons.lang.time.StopWatch;
14
 
import org.apache.log4j.Logger;
15
 
import org.hibernate.Session;
16
 
import org.hibernate.ejb.EntityManagerFactoryImpl;
17
 
 
18
 
public class TxHandle implements Comparable<TxHandle>, EntityTransaction {
19
 
  private static Logger                     LOG         = Logger.getLogger( TxHandle.class );
20
 
  private static ConcurrentNavigableMap<String, TxHandle> outstanding = new ConcurrentSkipListMap<String,TxHandle>();
21
 
 
22
 
  private EntityManager     em;
23
 
  private WeakReference<Session>           session;
24
 
  private EntityTransaction delegate;
25
 
  private StackTraceElement owner;
26
 
  private Calendar          startTime;
27
 
  private String            txUuid;
28
 
  private StopWatch         stopWatch;
29
 
 
30
 
  private volatile long splitTime = 0l;
31
 
  public TxHandle( String ctx ) {
32
 
    this.txUuid = String.format("%s:%s:%s",ctx, DebugUtil.TRACE ? EntityWrapper.getMyStackTraceElement( ) : "n.a", UUID.randomUUID( ).toString( ) );
33
 
    this.startTime = Calendar.getInstance( );
34
 
    this.stopWatch = new StopWatch( );
35
 
    this.stopWatch.start( );
36
 
    EntityManagerFactory anemf = ( EntityManagerFactoryImpl ) DatabaseUtil.getEntityManagerFactory( ctx );
37
 
    try {
38
 
      this.em = anemf.createEntityManager( );
39
 
      this.delegate = em.getTransaction( );
40
 
      this.delegate.begin( );
41
 
      this.session = new WeakReference<Session>(( Session ) em.getDelegate( ));
42
 
      outstanding.put( txUuid, this );
43
 
    } catch ( Throwable e ) {
44
 
      this.rollback( );
45
 
      LOG.error( e, e );
46
 
      throw new RuntimeException( e );
47
 
    }
48
 
  }
49
 
 
50
 
  public boolean isExpired() {
51
 
    long splitTime = split( );
52
 
    return (splitTime-DatabaseUtil.MAX_OPEN_TIME)>this.startTime.getTimeInMillis( );
53
 
  }
54
 
 
55
 
  public long splitOperation( ) {
56
 
    long oldSplit = splitTime;
57
 
    this.stopWatch.split( );
58
 
    splitTime = this.stopWatch.getSplitTime( );
59
 
    this.stopWatch.unsplit( );
60
 
    return splitTime - oldSplit;
61
 
  }
62
 
 
63
 
  public long split( ) {
64
 
    this.stopWatch.split( );
65
 
    splitTime = this.stopWatch.getSplitTime( );
66
 
    this.stopWatch.unsplit( );
67
 
    return splitTime;
68
 
  }
69
 
 
70
 
  public void rollback( ) {
71
 
    if( this.session != null ) {
72
 
      this.session.clear( );        
73
 
    }
74
 
    try {
75
 
      if ( this.delegate != null && this.delegate.isActive( ) ) {
76
 
        this.delegate.rollback( );
77
 
      }
78
 
    } catch( Throwable e ) {
79
 
      LOG.error( e, e );
80
 
    } finally {
81
 
      this.delegate = null;
82
 
      if( this.txUuid != null ) {
83
 
        outstanding.remove( this.txUuid );
84
 
      }
85
 
      if( this.em != null ) {
86
 
        this.em.close( );
87
 
      }
88
 
      this.em = null;
89
 
    }
90
 
  }
91
 
 
92
 
  private void verifyOpen( ) {
93
 
    if( this.delegate == null || this.em == null ) {
94
 
      throw new RuntimeException( "Calling a closed tx handle: " + this.txUuid );
95
 
    }
96
 
  }
97
 
 
98
 
  public void commit( ) {
99
 
    if( this.session != null ) {
100
 
      this.session.clear( );
101
 
    }
102
 
    this.verifyOpen( );
103
 
    try {
104
 
      this.delegate.commit( );
105
 
    } catch( RuntimeException e ) {
106
 
      if( this.delegate != null && this.delegate.isActive( ) ) {
107
 
        this.delegate.rollback( );
108
 
        LOG.debug( e, e );
109
 
        throw e;
110
 
      }
111
 
    } finally {
112
 
      this.delegate = null;
113
 
      outstanding.remove( this.txUuid );
114
 
      if( this.em != null ) {
115
 
        this.em.close( );
116
 
      }
117
 
      this.em = null;
118
 
    }
119
 
  }
120
 
  
121
 
  public static void printTxStatus( ) {
122
 
    for ( String uuid : outstanding.keySet( ) ) {
123
 
      TxHandle tx = outstanding.get( uuid );
124
 
      if( tx.isExpired() ) {
125
 
        LOG.error( LogUtil.subheader( "Long outstanding transaction handle for: " + uuid + " " + tx.txUuid ) );
126
 
        outstanding.remove( uuid );
127
 
      }
128
 
    }
129
 
  }
130
 
 
131
 
  public String getTxUuid( ) {
132
 
    this.split();
133
 
    return this.txUuid;
134
 
  }
135
 
 
136
 
  public boolean getRollbackOnly( ) {
137
 
    return delegate.getRollbackOnly( );
138
 
  }
139
 
 
140
 
  public boolean isActive( ) {
141
 
    return delegate.isActive( );
142
 
  }
143
 
 
144
 
  public void setRollbackOnly( ) {
145
 
    delegate.setRollbackOnly( );
146
 
  }
147
 
 
148
 
  public Session getSession( ) {
149
 
    if( session.get( ) == null ) {
150
 
      RuntimeException e = new RuntimeException( "Someone is calling a closed tx handle: " + this.txUuid );
151
 
      LOG.error( e, e );
152
 
      throw e;
153
 
    }
154
 
    return session.get( );
155
 
  }
156
 
 
157
 
  public Calendar getStartTime( ) {
158
 
    return startTime;
159
 
  }
160
 
 
161
 
  public EntityManager getEntityManager( ) {
162
 
    return this.em;
163
 
  }
164
 
 
165
 
  public void begin( ) {
166
 
    delegate.begin( );
167
 
  }
168
 
 
169
 
  @Override
170
 
  public int hashCode( ) {
171
 
    final int prime = 31;
172
 
    int result = 1;
173
 
    result = prime * result + ( ( owner == null ) ? 0 : owner.hashCode( ) );
174
 
    result = prime * result + ( ( startTime == null ) ? 0 : startTime.hashCode( ) );
175
 
    return result;
176
 
  }
177
 
 
178
 
  @Override
179
 
  public boolean equals( Object obj ) {
180
 
    if ( this == obj ) return true;
181
 
    if ( obj == null ) return false;
182
 
    if ( getClass( ) != obj.getClass( ) ) return false;
183
 
    TxHandle other = ( TxHandle ) obj;
184
 
    if ( owner == null ) {
185
 
      if ( other.owner != null ) return false;
186
 
    } else if ( !owner.equals( other.owner ) ) return false;
187
 
    if ( startTime == null ) {
188
 
      if ( other.startTime != null ) return false;
189
 
    } else if ( !startTime.equals( other.startTime ) ) return false;
190
 
    return true;
191
 
  }
192
 
 
193
 
  @Override
194
 
  public int compareTo( TxHandle o ) {
195
 
    return this.startTime.compareTo( o.getStartTime( ) );
196
 
  }
197
 
 
198
 
}