1 23 24 29 30 package com.sun.jdo.spi.persistence.support.sqlstore.impl; 31 32 import javax.transaction.*; 33 34 import java.util.Hashtable ; 35 import java.util.ArrayList ; 36 import java.sql.Connection ; 37 import javax.sql.DataSource ; 38 import java.util.Locale ; 39 import java.util.ResourceBundle ; 40 41 import com.sun.jdo.api.persistence.support.ConnectionFactory; 42 import com.sun.jdo.api.persistence.support.JDOException; 43 import com.sun.jdo.api.persistence.support.JDOUnsupportedOptionException; 44 import com.sun.jdo.api.persistence.support.JDOFatalInternalException; 45 import com.sun.jdo.api.persistence.support.JDOUserException; 46 import com.sun.jdo.api.persistence.support.JDODataStoreException; 47 48 import com.sun.jdo.spi.persistence.support.sqlstore.PersistenceManager; 49 import com.sun.jdo.spi.persistence.support.sqlstore.PersistenceManagerFactory; 50 import com.sun.jdo.spi.persistence.utility.I18NHelper; 51 52 import com.sun.jdo.spi.persistence.support.sqlstore.connection.ConnectionImpl; 53 54 import com.sun.jdo.spi.persistence.support.sqlstore.utility.*; 55 import com.sun.jdo.spi.persistence.support.sqlstore.ejb.EJBHelper; 56 import com.sun.jdo.spi.persistence.utility.logging.Logger; 57 import com.sun.jdo.spi.persistence.support.sqlstore.LogHelperTransaction; 58 59 89 public class TransactionImpl 90 implements com.sun.jdo.spi.persistence.support.sqlstore.Transaction { 91 98 static boolean tracing; 99 private static final int TRACE_THREADS = 0x01; 100 private static final int TRACE_RESOURCES = 0x02; 101 private static final int TRACE_SYNCHRONIZATIONS = 0x04; 102 private static final int TRACE_ONE_PHASE = 0x08; 103 104 111 static String globalLock = "TranGlobalLock"; 113 116 private int status; 117 118 121 private int timeout; 122 public static final int TRAN_DEFAULT_TIMEOUT = 0; 124 128 private int queryTimeout = 0; private int updateTimeout = 0; 131 134 private int threads; 135 public static final int TRAN_MAX_THREADS = 50; 137 141 private boolean startedCommit; 142 143 147 private boolean onePhase; 148 149 152 private Synchronization synchronization = null; 153 154 157 private ArrayList resources; 158 private static final int RESOURCE_START = 0; 159 private static final int RESOURCE_END = 1; 160 161 164 private PersistenceManagerFactory pmFactory = null; 165 166 169 private PersistenceManager persistenceManager = null; 170 171 174 private Object connectionFactory = null; 175 176 private javax.transaction.Transaction jta = null; 177 178 181 private boolean isDataSource = false; 182 183 186 private String username = null; 187 private String password = null; 188 189 192 private Connection _connection = null; 193 194 197 private int _connectionReferenceCount = 0; 198 199 203 private boolean retainValues = true; 204 205 209 private boolean restoreValues = false; 210 211 215 private boolean optimistic = true; 216 217 221 private boolean nontransactionalRead = true; 222 223 226 public static final int NON_MGD = 0; 227 public static final int CMT = 1; 228 public static final int BMT_UT = 2; 229 public static final int BMT_JDO = 3; 230 231 234 private int txType = -1; 235 236 239 private static Logger logger = LogHelperTransaction.getLogger(); 240 241 242 245 private final static ResourceBundle messages = I18NHelper.loadBundle( 246 TransactionImpl.class); 247 248 251 public TransactionImpl(PersistenceManager pm, String username, String password, int seconds) { 252 this.status = Status.STATUS_NO_TRANSACTION; 253 this.timeout = seconds; 254 this.startedCommit = false; 255 this.onePhase = false; 256 this.resources = new ArrayList (); 257 258 persistenceManager = pm; 259 this.username = username; 260 this.password = password; 261 262 pmFactory = (PersistenceManagerFactory)pm.getPersistenceManagerFactory(); 263 connectionFactory = pmFactory.getConnectionFactory(); 264 if (!(connectionFactory instanceof ConnectionFactory)) { 265 isDataSource = true; 266 } 267 268 optimistic = pmFactory.getOptimistic(); 269 retainValues = pmFactory.getRetainValues(); 270 nontransactionalRead = pmFactory.getNontransactionalRead(); 271 queryTimeout = pmFactory.getQueryTimeout(); 272 updateTimeout = pmFactory.getUpdateTimeout(); 273 274 } 275 276 279 public void setPersistenceManager(PersistenceManager pm) { 280 } 281 282 285 public com.sun.jdo.api.persistence.support.PersistenceManager getPersistenceManager() { 286 return persistenceManager.getCurrentWrapper(); 287 } 288 289 public boolean isActive() { 290 return (this.status == Status.STATUS_ACTIVE || 291 this.status == Status.STATUS_MARKED_ROLLBACK); 292 } 293 294 public void setRetainValues(boolean flag) { 295 if (isActive() && !optimistic && flag) 301 throw new JDOUnsupportedOptionException(I18NHelper.getMessage(messages, 302 "transaction.transactionimpl.setoptimistic.notallowed")); 304 persistenceManager.acquireExclusiveLock(); 308 309 try { 310 if (isActive() && !optimistic && flag) 312 throw new JDOUnsupportedOptionException(I18NHelper.getMessage(messages, 313 "transaction.transactionimpl.setoptimistic.notallowed")); 315 this.retainValues = flag; 316 317 if (flag) { 319 nontransactionalRead = flag; 320 persistenceManager.notifyNontransactionalRead(flag); 321 } 322 } finally { 323 persistenceManager.releaseExclusiveLock(); 324 } 325 } 326 327 public boolean getRetainValues() { 328 return retainValues; 329 } 330 331 public void setRestoreValues(boolean flag) { 332 if (isActive()) 338 throw new JDOUnsupportedOptionException(I18NHelper.getMessage(messages, 339 "transaction.transactionimpl.setoptimistic.notallowed")); 341 persistenceManager.acquireExclusiveLock(); 345 346 try { 347 if (isActive()) 349 throw new JDOUnsupportedOptionException(I18NHelper.getMessage(messages, 350 "transaction.transactionimpl.setoptimistic.notallowed")); 352 this.restoreValues = flag; 353 354 } finally { 355 persistenceManager.releaseExclusiveLock(); 356 } 357 } 358 359 public boolean getRestoreValues() { 360 return restoreValues; 361 } 362 363 364 public void setNontransactionalRead (boolean flag) { 365 if (isActive() && optimistic && !flag) 371 throw new JDOUnsupportedOptionException(I18NHelper.getMessage(messages, 372 "transaction.transactionimpl.setoptimistic.notallowed")); 374 persistenceManager.acquireExclusiveLock(); 378 379 try { 380 if (isActive() && optimistic && !flag) 382 throw new JDOUnsupportedOptionException(I18NHelper.getMessage(messages, 383 "transaction.transactionimpl.setoptimistic.notallowed")); 385 this.nontransactionalRead = flag; 386 persistenceManager.notifyNontransactionalRead(flag); 387 388 if (flag == false) { 390 retainValues = flag; 391 optimistic = flag; 392 393 persistenceManager.notifyOptimistic(flag); 395 } 396 } finally { 397 persistenceManager.releaseExclusiveLock(); 398 } 399 } 400 401 public boolean getNontransactionalRead() { 402 return nontransactionalRead; 403 } 404 405 410 public void setQueryTimeout(int timeout) { 411 queryTimeout = timeout; 412 } 413 414 419 public int getQueryTimeout() { 420 return queryTimeout; 421 } 422 423 428 public void setUpdateTimeout(int timeout) { 429 updateTimeout = timeout; 430 } 431 432 437 public int getUpdateTimeout() { 438 return updateTimeout; 439 } 440 441 public void setOptimistic(boolean flag) { 442 if (!isTerminated()) { 447 throw new JDOUnsupportedOptionException(I18NHelper.getMessage(messages, 448 "transaction.transactionimpl.setoptimistic.notallowed")); } 450 451 persistenceManager.acquireExclusiveLock(); 455 456 try { 457 if (isTerminated()) { 458 this.optimistic = flag; 459 460 if (flag) { 462 nontransactionalRead = flag; 463 persistenceManager.notifyNontransactionalRead(flag); 464 } 465 } else { 466 throw new JDOUnsupportedOptionException(I18NHelper.getMessage(messages, 467 "transaction.transactionimpl.setoptimistic.notallowed")); } 469 470 persistenceManager.notifyOptimistic(flag); 472 } finally { 473 persistenceManager.releaseExclusiveLock(); 474 } 475 } 476 477 public boolean getOptimistic() { 478 return optimistic; 479 } 480 481 public void setSynchronization(Synchronization sync) { 482 if (this.tracing) 483 this.traceCall("setSynchronization"); 485 persistenceManager.acquireExclusiveLock(); 486 487 try { 488 synchronization = sync; 489 490 if (this.tracing) { 491 this.traceCallInfo("setSynchronization", TRACE_SYNCHRONIZATIONS, null); 493 } 494 495 } finally { 496 persistenceManager.releaseExclusiveLock(); 497 } 498 } 499 500 public Synchronization getSynchronization() { 501 persistenceManager.acquireShareLock(); 502 503 try { 504 return synchronization; 505 } finally { 506 persistenceManager.releaseShareLock(); 507 } 508 } 509 510 public int getTransactionType() { 511 return txType; 512 } 513 514 520 public boolean verify(String username, String password) 521 { 522 if ((this.username != null && !this.username.equals(username)) || 523 (this.username == null && username != null) || 524 (this.password != null && !this.password.equals(password)) || 525 (this.password == null && password != null)) { 526 return false; 527 } 528 return true; 529 } 530 531 535 538 public void begin() { 539 540 persistenceManager.acquireExclusiveLock(); 541 542 try { 543 544 beginInternal(); 546 547 if (EJBHelper.isManaged()) { 549 txType = BMT_JDO; 550 try { 551 TransactionManager tm = EJBHelper.getLocalTransactionManager(); 552 553 tm.begin(); 554 jta = tm.getTransaction(); 555 EJBHelper.registerSynchronization(jta, this); 556 pmFactory.registerPersistenceManager(persistenceManager, jta); 557 558 } catch (JDOException e) { 559 throw e; 561 } catch (Exception e) { 562 throw new JDOFatalInternalException(I18NHelper.getMessage( 563 messages, "transaction.transactionimpl.begin.failedlocaltx"), e); } 565 } else { 566 txType = NON_MGD; 567 } 568 } finally { 569 persistenceManager.releaseExclusiveLock(); 570 } 571 } 572 573 576 private void beginInternal() { 577 this.setTrace(); 578 579 if (this.tracing) 580 this.traceCall("begin"); 582 if (this.isActive()) { 584 throw new JDOUserException(I18NHelper.getMessage(messages, 585 "transaction.transactionimpl.begin.notnew", this.statusString(this.status))); 587 588 } 589 this.setStatus(Status.STATUS_ACTIVE); 590 this.threads = 1; 591 } 592 593 596 public void begin(javax.transaction.Transaction t) { 597 598 persistenceManager.acquireExclusiveLock(); 599 600 try { 601 beginInternal(); 602 try { 603 jta = t; 604 EJBHelper.registerSynchronization(jta, this); 605 } catch (Exception e) { 606 throw new JDOFatalInternalException(I18NHelper.getMessage( 607 messages, "transaction.transactionimpl.begin.registersynchfailed"), e); } 609 610 txType = CMT; 611 } finally { 612 persistenceManager.releaseExclusiveLock(); 613 } 614 } 615 616 620 public void commit() { 621 622 persistenceManager.acquireExclusiveLock(); 623 624 try { 625 if (txType == CMT || txType == BMT_UT) { 626 throw new JDOUserException(I18NHelper.getMessage(messages, 628 "transaction.transactionimpl.mgd", "commit")); } else if (txType == BMT_JDO) { 630 try { 632 EJBHelper.getLocalTransactionManager().commit(); 633 return; 634 } catch (Exception e) { 635 throw new JDOException("", e); } 637 } 638 639 this.setTrace(); 640 641 if (this.tracing) 642 this.traceCall("commit"); 644 this.commitBefore(); 645 this.commitPrepare(); 646 this.commitComplete(); 647 this.notifyAfterCompletion(); 648 } finally { 649 persistenceManager.releaseExclusiveLock(); 650 } 651 } 652 653 656 public void beforeCompletion() { 657 658 if (txType == NON_MGD) { 659 throw new JDOUserException(I18NHelper.getMessage(messages, 661 "transaction.transactionimpl.nonmgd", "beforeCompletion")); } 663 664 Object o = null; 665 666 try { 667 o = EJBHelper.preInvoke(new Object [] {this, persistenceManager, jta}); 668 this.commitBefore(); this.commitPrepare(); this.commitComplete(); 671 } finally { 672 this.closeConnection(); 673 EJBHelper.postInvoke(o); 674 } 675 } 676 677 680 public void afterCompletion(int st) { 681 682 if (txType == NON_MGD) { 683 throw new JDOUserException(I18NHelper.getMessage(messages, 684 "transaction.transactionimpl.nonmgd", "afterCompletion")); } 686 st = EJBHelper.translateStatus(st); 688 if (this.tracing) { 689 this.traceCallInfo("afterCompletion", TRACE_SYNCHRONIZATIONS, this.statusString(st)); 691 } 692 693 if (st == Status.STATUS_ROLLEDBACK) { 694 this.setStatus(Status.STATUS_ROLLING_BACK); 695 this.internalRollback(); 696 } 697 698 if (st != this.status) { 699 if (synchronization != null) { 700 try { 702 synchronization.afterCompletion(st); 703 } catch (Exception ex) { 704 logger.log(Logger.WARNING, I18NHelper.getMessage( 705 messages, 706 "transaction.transactionimpl.syncmanager.aftercompletion", ex.getMessage())); 708 } 709 } 710 711 persistenceManager.forceClose(); 713 714 throw new JDOFatalInternalException(I18NHelper.getMessage(messages, 715 "transaction.transactionimpl.commitprepare.wrongstatus", "afterCompletion", this.statusString(this.status), this.statusString(st))); 718 } 719 720 this.notifyAfterCompletion(); 721 } 722 723 738 private void commitBefore() { 739 boolean rollbackOnly = false; boolean notified = false; 741 742 if (this.tracing) 743 this.traceCall("commitBefore"); 748 if ((this.status == Status.STATUS_ROLLING_BACK) 749 || (this.status == Status.STATUS_ROLLEDBACK)) { 750 throw new JDOUserException(I18NHelper.getMessage(messages, 751 "transaction.transactionimpl.rolledback", "commit", this.statusString(this.status))); 754 } 755 756 if (this.status == Status.STATUS_MARKED_ROLLBACK) { 757 rollbackOnly = true; 758 } else if (this.status != Status.STATUS_ACTIVE) { 759 throw new JDOUserException(I18NHelper.getMessage(messages, 760 "transaction.transactionimpl.commit_rollback.notactive", "commit", this.statusString(this.status))); 763 } 764 765 if (this.startedCommit) { 766 throw new JDOUserException(I18NHelper.getMessage(messages, 767 "transaction.transactionimpl.commitbefore.incommit", "commit")); } 770 this.startedCommit = true; 771 772 if (!rollbackOnly) { 777 this.notifyBeforeCompletion(); 778 notified = true; 779 780 if (this.status == Status.STATUS_ACTIVE) { this.setStatus(Status.STATUS_PREPARING); 782 } else if (this.status == Status.STATUS_MARKED_ROLLBACK) { 783 rollbackOnly = true; 784 } else { throw new JDOUserException(I18NHelper.getMessage(messages, 786 "transaction.transactionimpl.commitbefore.rolledback")); } 788 } 789 if (rollbackOnly && txType == NON_MGD) { 790 this.rollback(); 791 792 throw new JDOUserException(I18NHelper.getMessage(messages, 793 notified ? 794 "transaction.transactionimpl.commitbefore.rollbackonly_insync" : "transaction.transactionimpl.commitbefore.rollbackonly")); } 797 } 798 799 810 private void commitPrepare() { 811 if (this.tracing) 812 this.traceCall("commitPrepare"); 820 if (this.status != Status.STATUS_PREPARING) { 824 throw new JDOUserException(I18NHelper.getMessage(messages, 825 "transaction.transactionimpl.commitprepare.wrongstatus", "commitPrepare", "STATUS_PREPARING", this.statusString(this.status))); 829 } 830 831 if (this.resources.size() <= 1) 835 this.onePhase = true; 836 837 854 855 this.setStatus(Status.STATUS_PREPARED); 856 } 857 858 870 private void commitComplete() { 871 if (this.tracing) 872 this.traceCallInfo("commitComplete", TRACE_ONE_PHASE, null); 874 if (this.status == Status.STATUS_ROLLING_BACK) { 878 this.setStatus(Status.STATUS_ROLLING_BACK); internalRollback(); 880 } else if (this.status == Status.STATUS_PREPARED) { 881 this.setStatus(Status.STATUS_COMMITTING); 882 internalCommit(); 883 } else { 884 throw new JDOUserException(I18NHelper.getMessage(messages, 885 "transaction.transactionimpl.commitprepare.wrongstatus", "commitComplete", "STATUS_PREPARED", this.statusString(this.status))); 889 } 890 } 891 892 895 private void internalCommit() { 896 914 915 if (txType == NON_MGD) { 916 int error = this.commitConnection(); 917 if (error != INTERNAL_OK) { 918 this.forceRollback(); 919 throw new JDOUserException(I18NHelper.getMessage(messages, 920 "transaction.transactionimpl.commitcomplete.error", "Connection Error")); } 923 this.closeConnection(); 924 } 925 this.setStatus(Status.STATUS_COMMITTED); 926 } 927 928 932 public void rollback() { 933 934 persistenceManager.acquireExclusiveLock(); 935 936 try { 937 if (txType == CMT || txType == BMT_UT) { 938 throw new JDOUserException(I18NHelper.getMessage(messages, 940 "transaction.transactionimpl.mgd", "rollback")); } 942 943 this.setTrace(); 944 945 if (this.tracing) 946 this.traceCall("rollback"); 948 if ((this.status != Status.STATUS_ACTIVE) 949 && (this.status != Status.STATUS_MARKED_ROLLBACK)) { 950 957 throw new JDOUserException(I18NHelper.getMessage(messages, 958 "transaction.transactionimpl.commit_rollback.notactive", "rollback", this.statusString(this.status))); 961 } 962 963 this.setStatus(Status.STATUS_ROLLING_BACK); 964 965 this.internalRollback(); 966 this.closeConnection(); 967 968 if (txType == BMT_JDO) { 969 try { 971 EJBHelper.getLocalTransactionManager().rollback(); 972 } catch (Exception e) { 973 throw new JDOException("", e); } 975 } else { this.notifyAfterCompletion(); 983 } 984 } finally { 985 persistenceManager.releaseExclusiveLock(); 986 } 987 } 988 989 995 private void internalRollback() { 996 if (this.tracing) 997 this.traceCall("internalRollback"); 999 if (this.status == Status.STATUS_ROLLEDBACK) { 1000 return; 1001 } 1002 1003 if (this.status != Status.STATUS_ROLLING_BACK) { 1004 throw new JDOUserException(I18NHelper.getMessage(messages, 1005 "transaction.transactionimpl.commitprepare.wrongstatus", "internalRollback", "STATUS_ROLLING_BACK", this.statusString(this.status))); 1009 } 1010 1011 if (txType == NON_MGD) { 1012 this.rollbackConnection(); 1013 } 1014 1015 this.setStatus(Status.STATUS_ROLLEDBACK); 1016 } 1017 1018 1031 int forceRollback() { 1032 if (this.tracing) 1033 this.traceCall("forceRollback"); 1035 if ((this.status == Status.STATUS_ROLLING_BACK) || (this.status == Status.STATUS_ROLLEDBACK) || (this.status == Status.STATUS_COMMITTED) || (this.status == Status.STATUS_NO_TRANSACTION) ) { 1040 return this.status; 1041 } 1042 this.internalRollback(); 1043 this.notifyAfterCompletion(); 1044 1045 return this.status; 1046 } 1047 1048 1053 public void setRollbackOnly() { 1054 if (this.tracing) 1055 this.traceCall("setRollbackOnly"); 1057 if ((this.status == Status.STATUS_ROLLING_BACK) 1058 || (this.status == Status.STATUS_ROLLEDBACK) 1059 || (this.status == Status.STATUS_MARKED_ROLLBACK)) { 1060 return; 1064 } 1065 1066 if (txType != NON_MGD) { 1067 try { 1068 jta.setRollbackOnly(); 1069 } catch (Exception e) { 1070 throw new JDOException("", e); } 1072 } else { 1073 this.setStatus(Status.STATUS_MARKED_ROLLBACK); 1074 } 1075 1076 } 1077 1078 1084 public int getStatus() { 1085 synchronized (this.globalLock) { 1091 return this.status; 1092 } 1093 } 1094 1095 1099 1100 1105 boolean isTerminated() { 1106 synchronized (this.globalLock) { 1107 return ((this.status == Status.STATUS_COMMITTED) 1108 || (this.status == Status.STATUS_ROLLEDBACK) 1109 || (this.status == Status.STATUS_NO_TRANSACTION)); 1110 } 1111 } 1112 1113 1119 public boolean equals(Object o) { 1120 return (this == o); 1121 } 1122 1123 1127 1133 private void notifyBeforeCompletion() { 1139 if (synchronization != null) { 1140 try { 1141 synchronization.beforeCompletion(); 1142 } catch (Exception ex) { 1143 } 1147 } 1148 persistenceManager.beforeCompletion(); 1149 } 1150 1151 1155 private void notifyAfterCompletion() { 1156 try { 1157 persistenceManager.afterCompletion(this.status); 1158 1159 } finally { 1160 if (synchronization != null) { 1161 try { 1162 synchronization.afterCompletion(this.status); 1163 } catch (Exception ex) { 1164 logger.log(Logger.WARNING, I18NHelper.getMessage( 1165 messages, 1166 "transaction.transactionimpl.syncmanager.aftercompletion", ex.getMessage())); 1168 } 1169 } 1170 } 1171 1172 this.forget(); 1173 } 1174 1175 1176 1177 1180 private void setStatus(int status) { 1186 synchronized(this.globalLock) { 1187 if (this.tracing) { 1188 Object [] items= new Object [] {Thread.currentThread(),this.toString(), 1189 this.statusString(this.status), this.statusString(status), persistenceManager}; 1190 logger.finest("sqlstore.transactionimpl.status",items); } 1192 this.status = status; 1193 persistenceManager.notifyStatusChange(isActive()); 1194 } 1195 } 1196 1197 1200 private void forget() { 1201 if (this.tracing) 1202 this.traceCall("forget"); 1204 this.threads = 0; 1213 this.startedCommit = false; 1214 1215 if (_connection != null) { 1217 try { 1218 if (!_connection.isClosed()) { 1219 closeConnection(); 1220 throw new JDOFatalInternalException(I18NHelper.getMessage( 1221 messages, 1222 "transaction.transactionimpl.forget.connectionnotclosed")); } 1224 } catch (Exception e) { 1225 } 1226 _connection = null; 1227 } 1228 _connectionReferenceCount = 0; 1229 1230 this.resources.clear(); 1234 if (txType != NON_MGD) { 1235 persistenceManager.close(); 1236 } 1237 1238 jta = null; 1239 txType = NON_MGD; 1241 this.setTrace(); 1242 } 1243 1244 1248 1251 static void setTrace() { 1252 TransactionImpl.tracing = logger.isLoggable(Logger.FINEST); 1253 } 1254 1255 1258 private void traceCall(String call) { 1259 Object [] items = new Object []{Thread.currentThread(),this.toString(),call, 1260 this.statusString(this.status),txTypeString(), persistenceManager}; 1261 logger.finest("sqlstore.transactionimpl.call",items); } 1263 1264 1267 private void traceCallInfo(String call, int info, String s) { 1273 1274 StringBuffer logMessage = new StringBuffer (); 1276 logMessage.append("Thread.currentThread()").append("Tran[") .append(this.toString()).append("].").append(call) .append(": status = ").append(this.statusString(this.status)); 1280 if ((info & TRACE_THREADS) != 0) 1281 logMessage.append(", threads = " + this.threads); if ((info & TRACE_SYNCHRONIZATIONS) != 0) 1283 logMessage.append(", sync = " + this.synchronization); if ((info & TRACE_RESOURCES) != 0) 1285 logMessage.append(", resources = " + this.resources.size()); if ((info & TRACE_ONE_PHASE) != 0 && this.onePhase) 1287 logMessage.append(", onePhase = true"); if (s != null) 1289 logMessage.append(", " + s + " for " + persistenceManager); 1291 logger.finest("sqlstore.transactionimpl.general",logMessage.toString()); } 1293 1294 1297 private void traceCallString(String call, String info) { 1298 Object [] items = new Object [] {Thread.currentThread(),this.toString(),call,info,persistenceManager}; 1299 logger.finest("sqlstore.transactionimpl.call.info",items); } 1301 1302 1307 private String txTypeString() { 1308 switch (txType) { 1309 case NON_MGD: return "NON_MGD"; case CMT: return "CMT"; case BMT_UT: return "BMT_UT"; case BMT_JDO: return "BMT_JDO"; default: break; 1314 } 1315 return "UNKNOWN"; } 1317 1318 1324 public static String statusString(int status) { 1325 switch (status) { 1326 case Status.STATUS_ACTIVE: return "STATUS_ACTIVE"; case Status.STATUS_MARKED_ROLLBACK: return "STATUS_MARKED_ROLLBACK"; case Status.STATUS_PREPARED: return "STATUS_PREPARED"; case Status.STATUS_COMMITTED: return "STATUS_COMMITTED"; case Status.STATUS_ROLLEDBACK: return "STATUS_ROLLEDBACK"; case Status.STATUS_UNKNOWN: return "STATUS_UNKNOWN"; case Status.STATUS_NO_TRANSACTION: return "STATUS_NO_TRANSACTION"; case Status.STATUS_PREPARING: return "STATUS_PREPARING"; case Status.STATUS_COMMITTING: return "STATUS_COMMITTING"; case Status.STATUS_ROLLING_BACK: return "STATUS_ROLLING_BACK"; default: break; 1337 } 1338 return "STATUS_Invalid[" + status + "]"; } 1340 1341 1345 public synchronized Connection getConnection() { 1346 boolean debug = logger.isLoggable(Logger.FINEST); 1347 1348 if (_connection == null) { 1349 if (connectionFactory == null) { 1351 throw new JDOFatalInternalException(I18NHelper.getMessage(messages, 1352 "transaction.transactionimpl.getconnection.nullcf")); } 1354 1355 _connection = this.getConnectionInternal(); 1356 } 1357 1358 _connectionReferenceCount++; 1359 1360 if (debug) { 1361 Object [] items = new Object [] {_connection, Boolean.valueOf(optimistic), 1362 new Integer (_connectionReferenceCount) , persistenceManager}; 1363 logger.finest("sqlstore.transactionimpl.getconnection",items); } 1365 1366 if (!EJBHelper.isManaged()) { 1369 try { 1370 if ((!optimistic && isActive()) || startedCommit) { 1375 if (_connection.getAutoCommit()) { 1379 _connection.setAutoCommit(false); 1380 } 1381 } else { 1382 _connection.setAutoCommit(true); 1383 } 1384 } catch (java.sql.SQLException e) { 1385 logger.log(Logger.WARNING,"sqlstore.exception.log",e); } 1387 } 1388 1389 return _connection; 1390 } 1391 1392 1396 public void replaceConnection() { 1397 if (EJBHelper.isManaged()) { 1398 this.releaseConnection(); 1399 this.closeConnection(); 1400 this.getConnection(); 1401 } 1402 } 1403 1404 1409 public synchronized void releaseConnection() { 1410 boolean debug = logger.isLoggable(Logger.FINEST); 1411 1412 if (_connectionReferenceCount > 0) { 1413 _connectionReferenceCount--; 1414 } 1415 1416 if (debug) { 1417 Object [] items = new Object [] {Boolean.valueOf(optimistic), 1418 Boolean.valueOf(startedCommit), 1419 new Integer (_connectionReferenceCount) , persistenceManager}; 1420 logger.finest("sqlstore.transactionimpl.releaseconnection",items); } 1422 1423 if ( (!EJBHelper.isManaged() && optimistic == false) || startedCommit ) { 1425 return; 1427 } 1428 1429 if (_connectionReferenceCount == 0) { 1430 closeConnection(); 1435 } 1436 } 1437 1438 private Connection getConnectionInternal() { 1439 if (isDataSource) { 1440 try { 1441 if (EJBHelper.isManaged()) { 1442 if (isActive()) { 1444 return EJBHelper.getConnection(connectionFactory, 1445 username, password); 1446 } else { 1447 return EJBHelper.getNonTransactionalConnection( 1448 connectionFactory, username, password); 1449 } 1450 } else if (username != null) { 1451 return ((DataSource )connectionFactory).getConnection( 1452 username, password); 1453 } else { 1454 return ((DataSource )connectionFactory).getConnection(); 1455 } 1456 1457 } catch (java.sql.SQLException e) { 1458 String sqlState = e.getSQLState(); 1459 int errorCode = e.getErrorCode(); 1460 1461 if (sqlState == null) { 1462 throw new JDODataStoreException( 1463 I18NHelper.getMessage(messages, 1464 "connectionefactoryimpl.sqlexception", "null", "" + errorCode), e); } else { 1467 throw new JDODataStoreException( 1468 I18NHelper.getMessage(messages, 1469 "connectionefactoryimpl.sqlexception", sqlState, "" + errorCode), e); } 1472 } 1473 } else { 1474 return ((ConnectionFactory)connectionFactory).getConnection(); 1475 } 1476 } 1477 1478 1481 private void closeConnection() { 1482 boolean debug = logger.isLoggable(Logger.FINEST); 1483 if (debug) { 1484 Object [] items = new Object [] {_connection , persistenceManager}; 1485 logger.finest("sqlstore.transactionimpl.closeconnection",items); } 1487 try { 1488 if (_connection != null) { 1489 _connection.close(); 1490 } 1491 } catch (Exception e) { 1492 } 1494 _connection = null; 1495 } 1496 1497 1500 private void rollbackConnection() { 1501 boolean debug = logger.isLoggable(Logger.FINEST); 1502 if (debug) { 1503 Object [] items = new Object [] {_connection , persistenceManager}; 1504 logger.finest("sqlstore.transactionimpl.rollbackconnection",items); } 1506 if (_connection != null) { 1507 try { 1508 if (isDataSource) 1509 _connection.rollback(); 1510 else 1511 ((ConnectionImpl)_connection).internalRollback(); 1512 } catch (Exception e) { 1513 } 1515 } 1516 } 1517 private int INTERNAL_ERROR = 1; 1518 private int INTERNAL_OK = 0; 1519 1520 1523 private int commitConnection() { 1524 if (_connection != null) { 1525 try { 1526 if (isDataSource) 1527 _connection.commit(); 1528 else 1529 ((ConnectionImpl)_connection).internalCommit(); 1530 } catch (Exception e) { 1531 return INTERNAL_ERROR; 1532 } 1533 } 1534 return INTERNAL_OK; 1535 } 1536 1537 1538 1543 public String toString() { 1544 int i; 1545 Object o; 1546 1547 String s = " Transaction: \n status = " + this.statusString(this.status)+ "\n" + " Transaction Object = Transaction@" + this.hashCode() + "\n" + " threads = " + this.threads + "\n"; 1551 if (this.timeout != 0) 1552 s = s + " timeout = " + this.timeout + "\n"; if (this.startedCommit) 1554 s = s + " startedCommit = true\n"; if (this.onePhase) 1556 s = s + " onePhase = true\n"; 1558 if (synchronization != null) { 1559 s = s + "sync: " + synchronization + "\n"; } 1561 if (!this.resources.isEmpty()) { 1562 s = s + " # resources = " + this.resources.size() + "\n"; 1576 } 1577 return s; 1578 1579 } 1580} 1581 | Popular Tags |