1 21 22 package org.apache.derby.impl.services.locks; 23 24 import org.apache.derby.impl.services.locks.TableNameInfo; 25 26 import org.apache.derby.iapi.services.context.ContextService; 27 28 import org.apache.derby.iapi.reference.SQLState; 29 30 import org.apache.derby.iapi.services.locks.Latch; 31 import org.apache.derby.iapi.services.locks.Lockable; 32 import org.apache.derby.iapi.services.locks.VirtualLockTable; 33 import org.apache.derby.iapi.services.sanity.SanityManager; 34 35 import org.apache.derby.iapi.error.StandardException; 36 import org.apache.derby.iapi.sql.conn.LanguageConnectionContext; 37 import org.apache.derby.iapi.store.access.TransactionController; 38 39 import org.apache.derby.iapi.util.CheapDateFormatter; 40 41 import java.util.Enumeration ; 42 import java.util.Hashtable ; 43 44 48 49 public final class Timeout 50 { 51 public static final int TABLE_AND_ROWLOCK = VirtualLockTable.TABLE_AND_ROWLOCK; 52 public static final int ALL = VirtualLockTable.ALL; 53 54 public static final String newline = "\n"; 55 61 private TransactionController tc; 62 private TableNameInfo tabInfo; 63 64 65 private Latch currentLock; 66 67 private char[] outputRow; 68 69 private StringBuffer sb; 70 71 private Hashtable currentRow; 72 73 private final long currentTime; 74 75 private final Enumeration lockTable; 76 77 private final static String [] column = new String [9]; 88 private final static int LENGTHOFTABLE; 89 static 90 { 91 column[0] = "XID "; 92 column[1] = "TYPE "; 93 column[2] = "MODE"; 94 column[3] = "LOCKCOUNT"; 95 column[4] = "LOCKNAME "; 96 column[5] = "STATE"; 97 column[6] = "TABLETYPE / LOCKOBJ "; 98 column[7] = "INDEXNAME / CONTAINER_ID / (MODE for LATCH only) "; 99 column[8] = "TABLENAME / CONGLOM_ID "; 100 101 int length = 0; 102 for( int i = 0 ; i < column.length; i++ ) 103 { 104 length += column[i].length(); 105 } 106 length += column.length; if( SanityManager.DEBUG ) 108 { SanityManager.ASSERT( length == 256, "TIMEOUT_MONITOR: length of the row is not 256" ); 110 } 111 LENGTHOFTABLE = length; 112 } 113 private final static char LINE = '-'; 114 private final static char SEPARATOR = '|'; 115 116 122 private Timeout( Latch myTimeoutLock, Enumeration myLockTable, long time ) 123 { 124 currentLock = myTimeoutLock; 125 lockTable = myLockTable; 126 currentTime = time; 127 128 if( SanityManager.DEBUG ) 129 { 130 SanityManager.ASSERT( currentTime > 0, "TIMEOUT_MONITOR: currentTime is not set correctly" ); 131 } 132 } 133 134 140 private StandardException createException() 141 { 142 try 143 { 144 buildLockTableString(); 145 } 146 catch( StandardException se ) 147 { 148 return se; 149 } 150 151 StandardException se = StandardException.newException( SQLState.LOCK_TIMEOUT_LOG, sb.toString() ); 152 se.setReport( StandardException.REPORT_ALWAYS ); 153 return se; 154 } 155 156 159 private String buildLockTableString() throws StandardException 160 { 161 sb = new StringBuffer (8192); 162 outputRow = new char[ LENGTHOFTABLE ]; 163 int i; 165 LanguageConnectionContext lcc = (LanguageConnectionContext) 167 ContextService.getContext(LanguageConnectionContext.CONTEXT_ID); 168 if( lcc != null ) 169 tc = lcc.getTransactionExecute(); 170 171 try 172 { 173 tabInfo = new TableNameInfo( lcc, true ); 174 } 175 catch (Exception se) 176 { } 178 179 sb.append( newline ); 180 sb.append(CheapDateFormatter.formatDate(currentTime)); 181 sb.append( newline ); 182 for( i = 0; i < column.length; i++ ) 183 { 184 sb.append( column[i] ); 185 sb.append( SEPARATOR ); 186 } 187 sb.append( newline ); 188 189 for( i = 0; i < LENGTHOFTABLE; i++ ) 190 sb.append( LINE ); 191 192 sb.append( newline ); 193 194 if( currentLock != null ) 196 { 197 dumpLock( ); 198 if( timeoutInfoHash() ) 199 { 200 sb.append( "*** The following row is the victim ***" ); 201 sb.append( newline ); 202 sb.append( outputRow ); 203 sb.append( newline ); 204 sb.append( "*** The above row is the victim ***" ); 205 sb.append( newline ); 206 } 207 else 208 { 209 sb.append( "*** A victim was chosen, but it cannot be printed because the lockable object, " + currentLock + ", does not want to participate ***" ); 210 sb.append( newline ); 211 } 212 } 213 214 if( lockTable != null ) 216 { 217 while( lockTable.hasMoreElements() ) 218 { 219 currentLock = (Latch)lockTable.nextElement(); 220 dumpLock( ); 221 if( timeoutInfoHash() ) 222 { 223 sb.append( outputRow ); 224 sb.append( newline ); 225 } 226 else 227 { 228 sb.append( "*** A latch/lock, " + currentLock + ", exist in the lockTable that cannot be printed ***" ); 229 sb.append( newline ); 230 } 231 } 232 for( i = 0; i < LENGTHOFTABLE; i++ ) 233 sb.append( LINE ); 234 235 sb.append( newline ); 236 } 237 return sb.toString(); 238 } 239 240 247 static StandardException buildException( Latch timeoutLock, Enumeration table, long time ) 248 { 249 Timeout myTimeout = new Timeout( timeoutLock, table, time ); 250 return myTimeout.createException(); 251 } 252 253 257 public static String buildString( Enumeration table, long time ) throws StandardException 258 { 259 Timeout myTimeout = new Timeout( null, table, time); 260 return myTimeout.buildLockTableString(); 261 } 262 263 267 private void dumpLock() throws StandardException 268 { 269 Hashtable attributes = new Hashtable (17); 270 Object lock_type = currentLock.getQualifier(); 271 272 Lockable lockable = currentLock.getLockable(); 274 275 if( !lockable.lockAttributes(ALL, attributes) ) 277 { 278 currentRow = null; 279 return; 280 } 281 282 if( SanityManager.DEBUG ) 285 { 286 SanityManager.ASSERT(attributes.get(VirtualLockTable.LOCKNAME) != null, "lock table can only represent locks that have a LOCKNAME" ); 287 SanityManager.ASSERT(attributes.get(VirtualLockTable.LOCKTYPE) != null, "lock table can only represent locks that have a LOCKTYPE" ); 288 if( attributes.get(VirtualLockTable.CONTAINERID ) == null && 289 attributes.get(VirtualLockTable.CONGLOMID ) == null ) 290 SanityManager.THROWASSERT("lock table can only represent locks that are associated with a container or conglomerate"); 291 } 292 293 Long conglomId = (Long ) attributes.get(VirtualLockTable.CONGLOMID); 294 295 if( conglomId == null ) 296 { 297 if( attributes.get(VirtualLockTable.CONTAINERID) != null && tc != null ) 298 { 299 Long value = (Long )attributes.get(VirtualLockTable.CONTAINERID); 300 conglomId = new Long ( tc.findConglomid( value.longValue() ) ); 301 attributes.put( VirtualLockTable.CONGLOMID, conglomId ); 302 } 303 } 304 305 Long containerId = (Long ) attributes.get(VirtualLockTable.CONTAINERID); 306 307 if( containerId == null ) 308 { 309 if( conglomId != null && tc != null ) 310 { 311 try 312 { 313 containerId = new Long ( tc.findContainerid( conglomId.longValue() ) ); 314 attributes.put( VirtualLockTable.CONTAINERID, containerId ); 315 } 316 catch( Exception e ) 317 { 318 } 320 } 321 } 322 323 attributes.put( VirtualLockTable.LOCKOBJ, currentLock ); 324 attributes.put( VirtualLockTable.XACTID, currentLock.getCompatabilitySpace().toString() ); 325 attributes.put( VirtualLockTable.LOCKMODE, lock_type.toString() ); 326 attributes.put( VirtualLockTable.LOCKCOUNT, Integer.toString( currentLock.getCount() ) ); 327 attributes.put( VirtualLockTable.STATE, (currentLock.getCount() != 0 ) ? "GRANT" : "WAIT" ); 328 329 if( tabInfo != null && conglomId != null ) 330 { 331 try{ 332 String tableName = tabInfo.getTableName( conglomId ); 333 attributes.put( VirtualLockTable.TABLENAME, tableName ); 334 } 335 catch( NullPointerException e ) 336 { 337 attributes.put( VirtualLockTable.TABLENAME, conglomId ); 338 } 339 340 try 341 { 342 String indexName = tabInfo.getIndexName( conglomId ); 343 if( indexName != null ) 344 attributes.put( VirtualLockTable.INDEXNAME, indexName ); 345 else 346 { 347 if( attributes.get(VirtualLockTable.LOCKTYPE).equals("LATCH") ) 348 { attributes.put( VirtualLockTable.INDEXNAME, attributes.get(VirtualLockTable.LOCKMODE) ); 351 } 352 else 353 attributes.put( VirtualLockTable.INDEXNAME, "NULL" ); 354 } 355 }catch( Exception e ) 356 { if( VirtualLockTable.CONTAINERID != null ) 358 attributes.put( VirtualLockTable.INDEXNAME, VirtualLockTable.CONTAINERID ); 359 else 360 attributes.put( VirtualLockTable.INDEXNAME, "NULL" ); 361 } 362 363 String tableType = tabInfo.getTableType( conglomId ); 364 attributes.put( VirtualLockTable.TABLETYPE, tableType ); 365 } 366 else 367 { 368 if( conglomId != null ) 369 attributes.put( VirtualLockTable.TABLENAME, VirtualLockTable.CONGLOMID ); 370 else 371 attributes.put( VirtualLockTable.TABLENAME, "NULL" ); 372 373 if( VirtualLockTable.CONTAINERID != null ) 374 attributes.put( VirtualLockTable.INDEXNAME, VirtualLockTable.CONTAINERID ); 375 else 376 attributes.put( VirtualLockTable.INDEXNAME, "NULL" ); 377 378 attributes.put( VirtualLockTable.TABLETYPE, currentLock.toString() ); 379 } 380 currentRow = attributes; 381 } 382 383 389 private void cpArray( String toCp, int start, int end ) 390 { int i = 0; 392 int totalAllowWrite = end - start; 393 394 if( toCp != null ) 395 { 396 for( ; i < toCp.length() ; i++ ) 397 { 398 if( (totalAllowWrite-i) == 0 ) 399 break; 400 401 outputRow[ i + start ] = toCp.charAt(i); 402 } 403 } 404 for( ; i + start != end; i++ ) 405 outputRow[ i + start ] = ' '; 406 407 outputRow[ end ] = SEPARATOR; 408 } 409 410 414 private boolean timeoutInfoHash( ) 415 { 416 if( currentRow == null ) 417 return false; 418 419 String [] myData = new String [9]; 420 myData[0] = VirtualLockTable.XACTID; 421 myData[1] = VirtualLockTable.LOCKTYPE; 422 myData[2] = VirtualLockTable.LOCKMODE; 423 myData[3] = VirtualLockTable.LOCKCOUNT; 424 myData[4] = VirtualLockTable.LOCKNAME; 425 myData[5] = VirtualLockTable.STATE; 426 myData[6] = VirtualLockTable.TABLETYPE; 427 myData[7] = VirtualLockTable.INDEXNAME; 428 myData[8] = VirtualLockTable.TABLENAME; 429 430 431 int currentLength = 0; 432 for( int i = 0; i < myData.length; i++ ) 433 { 434 cpArray( currentRow.get( myData[i] ).toString(), currentLength , currentLength + column[i].length() ); 435 currentLength = currentLength + column[i].length() + 1; 437 } 438 return true; 439 } 440 } 441 442 | Popular Tags |