1 24 25 package org.continuent.sequoia.controller.requestmanager.distributed; 26 27 import java.io.Serializable ; 28 import java.sql.SQLException ; 29 import java.util.ArrayList ; 30 import java.util.Iterator ; 31 import java.util.List ; 32 33 import javax.management.NotCompliantMBeanException ; 34 35 import org.continuent.hedera.adapters.MulticastRequestAdapter; 36 import org.continuent.hedera.adapters.MulticastResponse; 37 import org.continuent.hedera.common.Member; 38 import org.continuent.sequoia.common.exceptions.NoMoreBackendException; 39 import org.continuent.sequoia.common.exceptions.NoResultAvailableException; 40 import org.continuent.sequoia.common.i18n.Translate; 41 import org.continuent.sequoia.controller.backend.result.ControllerResultSet; 42 import org.continuent.sequoia.controller.backend.result.ExecuteResult; 43 import org.continuent.sequoia.controller.backend.result.ExecuteUpdateResult; 44 import org.continuent.sequoia.controller.backend.result.GeneratedKeysResult; 45 import org.continuent.sequoia.controller.cache.result.AbstractResultCache; 46 import org.continuent.sequoia.controller.loadbalancer.AbstractLoadBalancer; 47 import org.continuent.sequoia.controller.loadbalancer.AllBackendsFailedException; 48 import org.continuent.sequoia.controller.recoverylog.RecoveryLog; 49 import org.continuent.sequoia.controller.requests.AbstractRequest; 50 import org.continuent.sequoia.controller.requests.AbstractWriteRequest; 51 import org.continuent.sequoia.controller.requests.SelectRequest; 52 import org.continuent.sequoia.controller.requests.StoredProcedure; 53 import org.continuent.sequoia.controller.requests.StoredProcedureCallResult; 54 import org.continuent.sequoia.controller.requests.UnknownWriteRequest; 55 import org.continuent.sequoia.controller.scheduler.AbstractScheduler; 56 import org.continuent.sequoia.controller.virtualdatabase.DistributedVirtualDatabase; 57 import org.continuent.sequoia.controller.virtualdatabase.protocol.DistributedAbort; 58 import org.continuent.sequoia.controller.virtualdatabase.protocol.DistributedCallableStatementExecute; 59 import org.continuent.sequoia.controller.virtualdatabase.protocol.DistributedCallableStatementExecuteQuery; 60 import org.continuent.sequoia.controller.virtualdatabase.protocol.DistributedCallableStatementExecuteUpdate; 61 import org.continuent.sequoia.controller.virtualdatabase.protocol.DistributedCommit; 62 import org.continuent.sequoia.controller.virtualdatabase.protocol.DistributedReleaseSavepoint; 63 import org.continuent.sequoia.controller.virtualdatabase.protocol.DistributedRequest; 64 import org.continuent.sequoia.controller.virtualdatabase.protocol.DistributedRollback; 65 import org.continuent.sequoia.controller.virtualdatabase.protocol.DistributedRollbackToSavepoint; 66 import org.continuent.sequoia.controller.virtualdatabase.protocol.DistributedSetSavepoint; 67 import org.continuent.sequoia.controller.virtualdatabase.protocol.DistributedStatementExecute; 68 import org.continuent.sequoia.controller.virtualdatabase.protocol.DistributedStatementExecuteQuery; 69 import org.continuent.sequoia.controller.virtualdatabase.protocol.DistributedStatementExecuteUpdate; 70 import org.continuent.sequoia.controller.virtualdatabase.protocol.DistributedStatementExecuteUpdateWithKeys; 71 import org.continuent.sequoia.controller.virtualdatabase.protocol.ExecRemoteStatementExecuteQuery; 72 import org.continuent.sequoia.controller.virtualdatabase.protocol.MessageTimeouts; 73 74 83 public class RAIDb1DistributedRequestManager extends DistributedRequestManager 84 { 85 99 public RAIDb1DistributedRequestManager(DistributedVirtualDatabase vdb, 100 AbstractScheduler scheduler, AbstractResultCache cache, 101 AbstractLoadBalancer loadBalancer, RecoveryLog recoveryLog, 102 long beginTimeout, long commitTimeout, long rollbackTimeout) 103 throws SQLException , NotCompliantMBeanException 104 { 105 super(vdb, scheduler, cache, loadBalancer, recoveryLog, beginTimeout, 106 commitTimeout, rollbackTimeout); 107 } 108 109 112 public ControllerResultSet distributedStatementExecuteQuery( 113 SelectRequest request) throws SQLException 114 { 115 return executeRequestReturningResultSet(request, 116 new DistributedStatementExecuteQuery(request), dvdb 117 .getMessageTimeouts().getExecReadRequestTimeout()); 118 } 119 120 123 public ControllerResultSet execRemoteStatementExecuteQuery( 124 SelectRequest request) throws SQLException 125 { 126 if (dvdb.isProcessMacroBeforeBroadcast()) 127 loadBalancer.handleMacros(request); 128 try 129 { 130 Iterator i = dvdb.getAllMemberButUs().iterator(); 133 SQLException error = null; 134 while (i.hasNext()) 135 { 136 Member controller = (Member) i.next(); 137 List groupMembers = new ArrayList (); 138 groupMembers.add(controller); 139 140 if (logger.isDebugEnabled()) 141 logger.debug("Sending request " 142 + request.getSqlShortForm(dvdb.getSqlShortFormLength()) 143 + (request.isAutoCommit() ? "" : " transaction " 144 + request.getTransactionId()) + " to " + controller); 145 146 MulticastResponse responses; 148 responses = dvdb.getMulticastRequestAdapter().multicastMessage( 149 groupMembers, 150 new ExecRemoteStatementExecuteQuery(request), 151 MulticastRequestAdapter.WAIT_ALL, 152 MessageTimeouts.getMinTimeout(dvdb.getMessageTimeouts() 153 .getExecReadRequestTimeout(), request.getTimeout() * 1000L)); 154 155 if (logger.isDebugEnabled()) 156 logger.debug("Request " 157 + request.getSqlShortForm(dvdb.getSqlShortFormLength()) 158 + " completed."); 159 160 Object ret = responses.getResult(controller); 161 if (ret instanceof ControllerResultSet) 162 return (ControllerResultSet) ret; 163 else if (ret instanceof SQLException ) 164 error = (SQLException ) ret; 165 } 166 167 if (error == null) 168 { 169 throw new NoMoreBackendException( 171 "No answer was received by the controller for remote StatementExecuteQuery"); 172 } 173 else 174 throw error; 175 } 176 catch (Exception e) 177 { 178 String msg = "An error occured while executing remote select request " 179 + request.getId(); 180 logger.warn(msg, e); 181 if (e instanceof SQLException ) 182 throw (SQLException ) e; 183 else 184 throw new SQLException (msg + " (" + e + ")"); 185 } 186 } 187 188 191 public ExecuteUpdateResult distributedStatementExecuteUpdate( 192 AbstractWriteRequest request) throws SQLException 193 { 194 return executeRequestReturningInt(request, 195 new DistributedStatementExecuteUpdate(request), dvdb 196 .getMessageTimeouts().getExecWriteRequestTimeout()); 197 } 198 199 202 public GeneratedKeysResult distributedStatementExecuteUpdateWithKeys( 203 AbstractWriteRequest request) throws SQLException 204 { 205 return executeRequestReturningGeneratedKeys(request, 206 new DistributedStatementExecuteUpdateWithKeys(request), dvdb 207 .getMessageTimeouts().getExecWriteRequestWithKeysTimeout()); 208 } 209 210 213 public ExecuteResult distributedStatementExecute(AbstractRequest request) 214 throws SQLException 215 { 216 return executeRequestReturningExecuteResult(request, 217 new DistributedStatementExecute(request), dvdb.getMessageTimeouts() 218 .getExecReadStoredProcedureTimeout()); 219 } 220 221 224 public ControllerResultSet distributedCallableStatementExecuteQuery( 225 StoredProcedure proc) throws SQLException 226 { 227 StoredProcedureCallResult result = executeRequestReturningStoredProcedureCallResult( 228 proc, new DistributedCallableStatementExecuteQuery(proc), dvdb 229 .getMessageTimeouts().getExecReadStoredProcedureTimeout()); 230 return (ControllerResultSet) result.getResult(); 231 } 232 233 236 public ExecuteUpdateResult distributedCallableStatementExecuteUpdate( 237 StoredProcedure proc) throws SQLException 238 { 239 StoredProcedureCallResult result = executeRequestReturningStoredProcedureCallResult( 240 proc, new DistributedCallableStatementExecuteUpdate(proc), dvdb 241 .getMessageTimeouts().getExecWriteStoredProcedureTimeout()); 242 return ((ExecuteUpdateResult) result.getResult()); 243 } 244 245 248 public ExecuteResult distributedCallableStatementExecute(StoredProcedure proc) 249 throws SQLException 250 { 251 StoredProcedureCallResult result = executeRequestReturningStoredProcedureCallResult( 252 proc, new DistributedCallableStatementExecute(proc), dvdb 253 .getMessageTimeouts().getExecReadStoredProcedureTimeout()); 254 return (ExecuteResult) result.getResult(); 255 } 256 257 266 private ExecuteResult executeRequestReturningExecuteResult( 267 AbstractRequest request, DistributedRequest requestMsg, 268 long messageTimeout) throws SQLException 269 { 270 if (dvdb.isProcessMacroBeforeBroadcast()) 271 loadBalancer.handleMacros(request); 272 try 273 { 274 ExecuteResult requestResult = null; 275 276 List groupMembers = dvdb.getAllMembers(); 277 278 MulticastResponse responses = multicastRequest(request, requestMsg, 279 messageTimeout, groupMembers); 280 281 ArrayList failedOnAllBackends = null; 283 ArrayList controllersWithoutBackends = null; 285 SQLException exception = null; 286 int size = groupMembers.size(); 287 List successfulControllers = null; 288 for (int i = 0; i < size; i++) 290 { 291 Member member = (Member) groupMembers.get(i); 292 if ((responses.getFailedMembers() != null) 293 && responses.getFailedMembers().contains(member)) 294 { 295 logger.warn("Controller " + member + " is suspected of failure."); 296 continue; 297 } 298 Object r = responses.getResult(member); 299 if (r instanceof ExecuteResult) 300 { 301 if (requestResult == null) 302 requestResult = (ExecuteResult) r; 303 } 304 else if (DistributedRequestManager.SUCCESSFUL_COMPLETION.equals(r)) 305 { 306 if (requestResult == null) 308 { 309 if (successfulControllers == null) 310 successfulControllers = new ArrayList (); 311 successfulControllers.add(member); 312 } 313 } 314 else if (r instanceof NoMoreBackendException) 315 { 316 if (controllersWithoutBackends == null) 317 controllersWithoutBackends = new ArrayList (); 318 controllersWithoutBackends.add(member); 319 if (logger.isDebugEnabled()) 320 logger.debug("Controller " + member 321 + " has no more backends to execute query (" + r + ")"); 322 } 323 else if (r instanceof Exception ) 324 { 325 if (failedOnAllBackends == null) 326 failedOnAllBackends = new ArrayList (); 327 failedOnAllBackends.add(member); 328 String msg = "Request " + request.getId() + " failed on controller " 329 + member + " (" + r + ")"; 330 logger.warn(msg); 331 if (r instanceof SQLException ) 332 exception = (SQLException ) r; 333 else 334 { 335 exception = new SQLException ("Internal exception " + r); 336 exception.initCause((Throwable ) r); 337 } 338 } 339 else 340 { 341 if (failedOnAllBackends == null) 342 failedOnAllBackends = new ArrayList (); 343 failedOnAllBackends.add(member); 344 if (logger.isWarnEnabled()) 345 logger.warn("Unexpected answer from controller " + member + " (" 346 + r + ") for request " 347 + request.getSqlShortForm(vdb.getSqlShortFormLength())); 348 } 349 } 350 351 if ((requestResult == null) && (successfulControllers != null)) 352 { try 355 { 356 requestResult = (ExecuteResult) getRequestResultFromFailoverCache( 357 successfulControllers, request.getId()); 358 } 359 catch (NoResultAvailableException e) 360 { 361 exception = new SQLException ( 362 "Request '" 363 + request 364 + "' was successfully executed on remote controllers, but all successful controllers failed before retrieving result"); 365 } 366 } 367 368 if ((controllersWithoutBackends != null) || (failedOnAllBackends != null)) 369 { StoredProcedure proc = new StoredProcedure(request.getSqlOrTemplate(), 373 request.getEscapeProcessing(), request.getTimeout(), request 374 .getLineSeparator()); 375 proc.setIsAutoCommit(request.isAutoCommit()); 376 proc.setTransactionId(request.getTransactionId()); 377 proc.setTransactionIsolation(request.getTransactionIsolation()); 378 proc.setId(request.getId()); 379 380 386 boolean success = (requestResult != null || successfulControllers != null); 387 388 notifyRequestCompletion(proc, success, true, failedOnAllBackends); 389 390 notifyRequestCompletion(proc, success, false, 392 controllersWithoutBackends); 393 } 394 395 if (requestResult != null) 396 { 397 if (logger.isDebugEnabled()) 398 logger.debug("Request " + request.getId() 399 + " completed successfully."); 400 return requestResult; 401 } 402 403 405 if (exception != null) 406 throw exception; 407 else 408 { 409 String msg = "Request '" 410 + request.getSqlShortForm(vdb.getSqlShortFormLength()) 411 + "' failed on all controllers"; 412 logger.warn(msg); 413 throw new SQLException (msg); 414 } 415 } 416 catch (SQLException e) 417 { 418 String msg = Translate 419 .get("loadbalancer.request.failed", new String []{ 420 request.getSqlShortForm(vdb.getSqlShortFormLength()), 421 e.getMessage()}); 422 logger.warn(msg); 423 throw e; 424 } 425 } 426 427 436 private GeneratedKeysResult executeRequestReturningGeneratedKeys( 437 AbstractRequest request, DistributedRequest requestMsg, 438 long messageTimeout) throws SQLException 439 { 440 if (dvdb.isProcessMacroBeforeBroadcast()) 441 loadBalancer.handleMacros(request); 442 try 443 { 444 GeneratedKeysResult requestResult = null; 445 446 List groupMembers = dvdb.getAllMembers(); 447 448 MulticastResponse responses = multicastRequest(request, requestMsg, 449 messageTimeout, groupMembers); 450 451 ArrayList failedOnAllBackends = null; 453 ArrayList inconsistentControllers = null; 455 ArrayList controllersWithoutBackends = null; 457 SQLException exception = null; 458 List successfulControllers = null; 459 int size = groupMembers.size(); 460 for (int i = 0; i < size; i++) 462 { 463 Member member = (Member) groupMembers.get(i); 464 if ((responses.getFailedMembers() != null) 465 && responses.getFailedMembers().contains(member)) 466 { 467 logger.warn("Controller " + member + " is suspected of failure."); 468 continue; 469 } 470 Object r = responses.getResult(member); 471 if (r instanceof GeneratedKeysResult) 472 { 473 if (requestResult == null) 474 { 475 requestResult = (GeneratedKeysResult) r; 476 } 477 else 478 { 479 if (requestResult.getUpdateCount() != ((GeneratedKeysResult) r) 480 .getUpdateCount()) 481 { 482 if (inconsistentControllers == null) 483 inconsistentControllers = new ArrayList (); 484 inconsistentControllers.add(member); 485 logger 486 .error("Controller " + member 487 + " returned an inconsistent results (" + requestResult 488 + " when expecting " + r + ") for request " 489 + request.getId()); 490 } 491 } 492 } 493 else if (DistributedRequestManager.SUCCESSFUL_COMPLETION.equals(r)) 494 { 495 if (requestResult == null) 497 { 498 if (successfulControllers == null) 499 successfulControllers = new ArrayList (); 500 successfulControllers.add(member); 501 } 502 } 503 else if (r instanceof NoMoreBackendException) 504 { 505 if (controllersWithoutBackends == null) 506 controllersWithoutBackends = new ArrayList (); 507 controllersWithoutBackends.add(member); 508 if (logger.isDebugEnabled()) 509 logger.debug("Controller " + member 510 + " has no more backends to execute query (" + r + ")"); 511 } 512 else if (r instanceof Exception ) 513 { 514 if (failedOnAllBackends == null) 515 failedOnAllBackends = new ArrayList (); 516 failedOnAllBackends.add(member); 517 String msg = "Request " + request.getId() + " failed on controller " 518 + member + " (" + r + ")"; 519 logger.warn(msg); 520 if (r instanceof SQLException ) 521 exception = (SQLException ) r; 522 else 523 { 524 exception = new SQLException ("Internal exception " + r); 525 exception.initCause((Throwable ) r); 526 } 527 } 528 else 529 { 530 if (failedOnAllBackends == null) 531 failedOnAllBackends = new ArrayList (); 532 failedOnAllBackends.add(member); 533 if (logger.isWarnEnabled()) 534 logger.warn("Unexpected answer from controller " + member + " (" 535 + r + ") for request " 536 + request.getSqlShortForm(vdb.getSqlShortFormLength())); 537 } 538 } 539 540 if ((requestResult == null) && (successfulControllers != null)) 541 { try 544 { 545 requestResult = (GeneratedKeysResult) getRequestResultFromFailoverCache( 546 successfulControllers, request.getId()); 547 } 548 catch (NoResultAvailableException e) 549 { 550 exception = new SQLException ( 551 "Request '" 552 + request 553 + "' was successfully executed on remote controllers, but all successful controllers failed before retrieving result"); 554 } 555 } 556 557 563 boolean success = (requestResult != null || successfulControllers != null); 564 notifyRequestCompletion(request, success, true, failedOnAllBackends); 565 566 notifyRequestCompletion(request, success, false, 568 controllersWithoutBackends); 569 570 if (inconsistentControllers != null) 571 { notifyControllerInconsistency(request, inconsistentControllers); 573 } 574 575 if (requestResult != null) 576 { 577 if (logger.isDebugEnabled()) 578 logger.debug("Request " + request.getId() 579 + " completed successfully."); 580 return requestResult; 581 } 582 583 585 if (exception != null) 586 throw exception; 587 else 588 { 589 String msg = "Request '" + request + "' failed on all controllers"; 590 logger.warn(msg); 591 throw new SQLException (msg); 592 } 593 } 594 catch (SQLException e) 595 { 596 String msg = Translate 597 .get("loadbalancer.request.failed", new String []{ 598 request.getSqlShortForm(vdb.getSqlShortFormLength()), 599 e.getMessage()}); 600 logger.warn(msg); 601 throw e; 602 } 603 } 604 605 614 private ExecuteUpdateResult executeRequestReturningInt( 615 AbstractRequest request, DistributedRequest requestMsg, 616 long messageTimeout) throws SQLException 617 { 618 if (dvdb.isProcessMacroBeforeBroadcast()) 619 loadBalancer.handleMacros(request); 620 try 621 { 622 ExecuteUpdateResult requestResult = null; 623 624 List groupMembers = dvdb.getAllMembers(); 625 626 MulticastResponse responses = multicastRequest(request, requestMsg, 627 messageTimeout, groupMembers); 628 629 ArrayList failedOnAllBackends = null; 631 ArrayList inconsistentControllers = null; 633 ArrayList controllersWithoutBackends = null; 635 SQLException exception = null; 636 int size = groupMembers.size(); 637 for (int i = 0; i < size; i++) 639 { 640 Member member = (Member) groupMembers.get(i); 641 if ((responses.getFailedMembers() != null) 642 && responses.getFailedMembers().contains(member)) 643 { 644 logger.warn("Controller " + member + " is suspected of failure."); 645 continue; 646 } 647 Object r = responses.getResult(member); 648 if (r instanceof ExecuteUpdateResult) 649 { 650 if (requestResult == null) 651 requestResult = (ExecuteUpdateResult) r; 652 else 653 { 654 if (requestResult.getUpdateCount() != ((ExecuteUpdateResult) r) 655 .getUpdateCount()) 656 { 657 if (inconsistentControllers == null) 658 inconsistentControllers = new ArrayList (); 659 inconsistentControllers.add(member); 660 logger.error("Controller " + member 661 + " returned an inconsistent results (" 662 + requestResult.getUpdateCount() + " when expecting " 663 + ((ExecuteUpdateResult) r).getUpdateCount() 664 + ") for request " + request.getId()); 665 } 666 } 667 } 668 else if (r instanceof NoMoreBackendException) 669 { 670 if (controllersWithoutBackends == null) 671 controllersWithoutBackends = new ArrayList (); 672 controllersWithoutBackends.add(member); 673 if (logger.isDebugEnabled()) 674 logger.debug("Controller " + member 675 + " has no more backends to execute query (" + r + ")"); 676 } 677 else if (r instanceof Exception ) 678 { 679 if (failedOnAllBackends == null) 680 failedOnAllBackends = new ArrayList (); 681 failedOnAllBackends.add(member); 682 String msg = "Request " + request.getId() + " failed on controller " 683 + member + " (" + r + ")"; 684 logger.debug(msg); 686 if (r instanceof SQLException ) 687 exception = (SQLException ) r; 688 else 689 { 690 exception = new SQLException ("Internal exception " + r); 691 exception.initCause((Throwable ) r); 692 } 693 } 694 else 695 { 696 if (failedOnAllBackends == null) 697 failedOnAllBackends = new ArrayList (); 698 failedOnAllBackends.add(member); 699 if (logger.isWarnEnabled()) 700 logger.warn("Unexpected answer from controller " + member + " (" 701 + r + ") for request " 702 + request.getSqlShortForm(vdb.getSqlShortFormLength())); 703 } 704 } 705 706 int requestUpdateCount = -1; 707 if (requestResult != null) 708 requestUpdateCount = requestResult.getUpdateCount(); 709 710 notifyRequestCompletion(request, requestResult != null, true, 713 failedOnAllBackends, requestUpdateCount); 714 715 notifyRequestCompletion(request, requestResult != null, false, 717 controllersWithoutBackends, requestUpdateCount); 718 719 if (inconsistentControllers != null) 720 { notifyControllerInconsistency(request, inconsistentControllers); 722 } 723 724 if (requestResult != null) 725 { 726 if (logger.isDebugEnabled()) 727 logger.debug("Request " + request.getId() 728 + " completed successfully."); 729 return requestResult; 730 } 731 732 734 if (exception != null) 735 throw exception; 736 else 737 { 738 String msg = "Request '" + request + "' failed on all controllers"; 739 logger.warn(msg); 740 throw new SQLException (msg); 741 } 742 } 743 catch (SQLException e) 744 { 745 String msg = Translate 746 .get("loadbalancer.request.failed", new String []{ 747 request.getSqlShortForm(vdb.getSqlShortFormLength()), 748 e.getMessage()}); 749 logger.debug(msg); 751 throw e; 752 } 753 } 754 755 764 private ControllerResultSet executeRequestReturningResultSet( 765 AbstractRequest request, DistributedRequest requestMsg, 766 long messageTimeout) throws SQLException 767 { 768 if (dvdb.isProcessMacroBeforeBroadcast()) 769 loadBalancer.handleMacros(request); 770 try 771 { 772 ControllerResultSet requestResult = null; 773 774 List groupMembers = dvdb.getAllMembers(); 775 776 MulticastResponse responses = multicastRequest(request, requestMsg, 777 messageTimeout, groupMembers); 778 779 ArrayList failedOnAllBackends = null; 781 ArrayList controllersWithoutBackends = null; 783 SQLException exception = null; 784 int size = groupMembers.size(); 785 List successfulControllers = null; 786 for (int i = 0; i < size; i++) 788 { 789 Member member = (Member) groupMembers.get(i); 790 if ((responses.getFailedMembers() != null) 791 && responses.getFailedMembers().contains(member)) 792 { 793 logger.warn("Controller " + member + " is suspected of failure."); 794 continue; 795 } 796 Object r = responses.getResult(member); 797 if (r instanceof ControllerResultSet) 798 { 799 if (requestResult == null) 800 requestResult = (ControllerResultSet) r; 801 } 802 else if (DistributedRequestManager.SUCCESSFUL_COMPLETION.equals(r)) 803 { 804 if (requestResult == null) 806 { 807 if (successfulControllers == null) 808 successfulControllers = new ArrayList (); 809 successfulControllers.add(member); 810 } 811 } 812 else if (r instanceof NoMoreBackendException) 813 { 814 if (controllersWithoutBackends == null) 815 controllersWithoutBackends = new ArrayList (); 816 controllersWithoutBackends.add(member); 817 if (logger.isDebugEnabled()) 818 logger.debug("Controller " + member 819 + " has no more backends to execute query (" + r + ")"); 820 } 821 else if (r instanceof Exception ) 822 { 823 if (failedOnAllBackends == null) 824 failedOnAllBackends = new ArrayList (); 825 failedOnAllBackends.add(member); 826 String msg = "Request " + request.getId() + " failed on controller " 827 + member + " (" + r + ")"; 828 logger.warn(msg); 829 if (r instanceof SQLException ) 830 exception = (SQLException ) r; 831 else 832 { 833 exception = new SQLException ("Internal exception " + r); 834 exception.initCause((Throwable ) r); 835 } 836 } 837 else 838 { 839 if (failedOnAllBackends == null) 840 failedOnAllBackends = new ArrayList (); 841 failedOnAllBackends.add(member); 842 if (logger.isWarnEnabled()) 843 logger.warn("Unexpected answer from controller " + member + " (" 844 + r + ") for request " 845 + request.getSqlShortForm(vdb.getSqlShortFormLength())); 846 } 847 } 848 849 if ((requestResult == null) && (successfulControllers != null)) 850 { try 853 { 854 requestResult = (ControllerResultSet) getRequestResultFromFailoverCache( 855 successfulControllers, request.getId()); 856 } 857 catch (NoResultAvailableException e) 858 { 859 exception = new SQLException ( 860 "Request '" 861 + request 862 + "' was successfully executed on remote controllers, but all successful controllers failed before retrieving result"); 863 } 864 } 865 866 872 boolean success = (requestResult != null || successfulControllers != null); 873 874 notifyRequestCompletion(request, success, true, failedOnAllBackends); 875 876 notifyRequestCompletion(request, success, false, 878 controllersWithoutBackends); 879 880 if (requestResult != null) 881 { 882 if (logger.isDebugEnabled()) 883 logger.debug("Request " + request.getId() 884 + " completed successfully."); 885 return requestResult; 886 } 887 888 890 if (exception != null) 891 throw exception; 892 else 893 { 894 String msg = "Request '" + request + "' failed on all controllers"; 895 logger.warn(msg); 896 throw new SQLException (msg); 897 } 898 } 899 catch (SQLException e) 900 { 901 String msg = Translate 902 .get("loadbalancer.request.failed", new String []{ 903 request.getSqlShortForm(vdb.getSqlShortFormLength()), 904 e.getMessage()}); 905 logger.warn(msg); 906 throw e; 907 } 908 } 909 910 920 private StoredProcedureCallResult executeRequestReturningStoredProcedureCallResult( 921 StoredProcedure proc, DistributedRequest requestMsg, long messageTimeout) 922 throws SQLException 923 { 924 if (dvdb.isProcessMacroBeforeBroadcast()) 925 loadBalancer.handleMacros(proc); 926 try 927 { 928 StoredProcedureCallResult result = null; 929 930 List groupMembers = dvdb.getAllMembers(); 931 932 MulticastResponse responses = multicastRequest(proc, requestMsg, 933 messageTimeout, groupMembers); 934 935 ArrayList failedOnAllBackends = null; 937 ArrayList controllersWithoutBackends = null; 939 SQLException exception = null; 940 int size = groupMembers.size(); 941 List successfulControllers = null; 942 for (int i = 0; i < size; i++) 944 { 945 Member member = (Member) groupMembers.get(i); 946 if ((responses.getFailedMembers() != null) 947 && responses.getFailedMembers().contains(member)) 948 { 949 logger.warn("Controller " + member + " is suspected of failure."); 950 continue; 951 } 952 Object r = responses.getResult(member); 953 if (r instanceof StoredProcedureCallResult) 954 { 955 if (result == null) 956 result = (StoredProcedureCallResult) r; 957 } 958 else if (DistributedRequestManager.SUCCESSFUL_COMPLETION.equals(r)) 959 { 960 if (result == null) 962 { 963 if (successfulControllers == null) 964 successfulControllers = new ArrayList (); 965 successfulControllers.add(member); 966 } 967 } 968 else if (r instanceof NoMoreBackendException) 969 { 970 if (controllersWithoutBackends == null) 971 controllersWithoutBackends = new ArrayList (); 972 controllersWithoutBackends.add(member); 973 if (logger.isDebugEnabled()) 974 logger.debug("Controller " + member 975 + " has no more backends to execute query (" + r + ")"); 976 } 977 else if (r instanceof Exception ) 978 { 979 if (failedOnAllBackends == null) 980 failedOnAllBackends = new ArrayList (); 981 failedOnAllBackends.add(member); 982 String msg = "Request " + proc.getId() + " failed on controller " 983 + member + " (" + r + ")"; 984 logger.warn(msg); 985 if (r instanceof SQLException ) 986 exception = (SQLException ) r; 987 else 988 { 989 exception = new SQLException ("Internal exception " + r); 990 exception.initCause((Throwable ) r); 991 } 992 } 993 else 994 { 995 if (failedOnAllBackends == null) 996 failedOnAllBackends = new ArrayList (); 997 failedOnAllBackends.add(member); 998 if (logger.isWarnEnabled()) 999 logger.warn("Unexpected answer from controller " + member + " (" 1000 + r + ") for request " 1001 + proc.getSqlShortForm(vdb.getSqlShortFormLength())); 1002 } 1003 } 1004 1005 if ((result == null) && (successfulControllers != null)) 1006 { 1009 try 1010 { 1011 result = (StoredProcedureCallResult) getRequestResultFromFailoverCache( 1012 successfulControllers, proc.getId()); 1013 } 1014 catch (NoResultAvailableException e) 1015 { 1016 exception = new SQLException ( 1017 "Request '" 1018 + proc 1019 + "' was successfully executed on remote controllers, but all successful controllers failed before retrieving result"); 1020 } 1021 1022 } 1023 1024 1030 boolean success = (result != null || successfulControllers != null); 1031 1032 notifyRequestCompletion(proc, success, true, failedOnAllBackends); 1033 1034 notifyRequestCompletion(proc, success, false, controllersWithoutBackends); 1036 1037 if (result != null) 1038 { 1039 proc.copyNamedAndOutParameters(result.getStoredProcedure()); 1040 if (logger.isDebugEnabled()) 1041 logger.debug("Request " + proc.getId() + " completed successfully."); 1042 return result; 1043 } 1044 1045 1047 if (exception != null) 1048 throw exception; 1049 else 1050 { 1051 String msg = "Request '" + proc + "' failed on all controllers"; 1052 logger.warn(msg); 1053 throw new SQLException (msg); 1054 } 1055 } 1056 catch (SQLException e) 1057 { 1058 String msg = Translate.get("loadbalancer.request.failed", new String []{ 1059 proc.getSqlShortForm(vdb.getSqlShortFormLength()), e.getMessage()}); 1060 logger.warn(msg); 1061 throw e; 1062 } 1063 } 1064 1065 1075 private MulticastResponse multicastRequest(AbstractRequest request, 1076 Serializable requestMsg, long messageTimeout, List groupMembers) 1077 throws SQLException 1078 { 1079 if (logger.isDebugEnabled()) 1080 logger.debug("Broadcasting request " 1081 + request.getSqlShortForm(dvdb.getSqlShortFormLength()) 1082 + (request.isAutoCommit() ? "" : " transaction " 1083 + request.getTransactionId()) + " to all controllers (" 1084 + dvdb.getChannel().getLocalMembership() + "->" 1085 + groupMembers.toString() + ")"); 1086 1087 MulticastResponse responses; 1089 try 1090 { 1091 responses = dvdb.getMulticastRequestAdapter().multicastMessage( 1093 groupMembers, 1094 requestMsg, 1095 MulticastRequestAdapter.WAIT_ALL, 1096 MessageTimeouts.getMinTimeout(messageTimeout, 1097 request.getTimeout() * 1000L)); 1098 } 1099 catch (Exception e) 1100 { 1101 String msg = "An error occured while executing distributed request " 1102 + request.getId(); 1103 logger.warn(msg, e); 1104 throw new SQLException (msg + " (" + e + ")"); 1105 } 1106 1107 if (logger.isDebugEnabled()) 1108 logger.debug("Request " 1109 + request.getSqlShortForm(dvdb.getSqlShortFormLength()) 1110 + " completed."); 1111 1112 if (responses.getFailedMembers() != null) 1113 { logger.warn(responses.getFailedMembers().size() 1115 + " controller(s) died during execution of request " 1116 + request.getId()); 1117 } 1118 return responses; 1119 } 1120 1121 1125 public void distributedAbort(String login, long transactionId) 1126 throws SQLException 1127 { 1128 try 1129 { 1130 List groupMembers = dvdb.getAllMembers(); 1131 1132 AbstractRequest abortRequest = new UnknownWriteRequest("abort", false, 0, 1133 "\n"); 1134 abortRequest.setLogin(login); 1135 abortRequest.setTransactionId(transactionId); 1136 abortRequest.setIsAutoCommit(false); 1137 1138 MulticastResponse responses = multicastRequest(abortRequest, 1139 new DistributedAbort(login, transactionId), dvdb.getMessageTimeouts() 1140 .getRollbackTimeout(), groupMembers); 1141 1142 if (logger.isDebugEnabled()) 1143 logger.debug("Abort of transaction " + transactionId + " completed."); 1144 1145 ArrayList controllersWithException = null; 1147 SQLException exception = null; 1148 int size = groupMembers.size(); 1149 boolean success = false; 1150 for (int i = 0; i < size; i++) 1152 { 1153 Member member = (Member) groupMembers.get(i); 1154 if ((responses.getFailedMembers() != null) 1155 && responses.getFailedMembers().contains(member)) 1156 { 1157 logger.warn("Controller " + member + " is suspected of failure."); 1158 continue; 1159 } 1160 Object r = responses.getResult(member); 1161 if (r instanceof Boolean ) 1162 { 1163 if (((Boolean ) r).booleanValue()) 1164 success = true; 1165 else 1166 logger.error("Unexpected result for controller " + member); 1167 } 1168 else if (r instanceof Exception ) 1169 { 1170 if (controllersWithException == null) 1171 controllersWithException = new ArrayList (); 1172 controllersWithException.add(member); 1173 if (logger.isDebugEnabled()) 1174 logger.debug("Controller " + member 1175 + " has no more backends to abort transaction " 1176 + transactionId + " (" + r + ")"); 1177 } 1178 } 1179 1180 notifyRequestCompletion(abortRequest, success, false, 1182 controllersWithException); 1183 1184 if (success) 1185 return; 1187 if (exception != null) 1188 throw exception; 1189 1190 1192 String msg = "Transaction " + transactionId 1193 + " failed to abort on all controllers"; 1194 logger.warn(msg); 1195 throw new SQLException (msg); 1196 } 1197 catch (SQLException e) 1198 { 1199 String msg = "Transaction " + transactionId + " abort failed (" + e + ")"; 1200 logger.warn(msg); 1201 throw e; 1202 } 1203 } 1204 1205 1209 public void distributedCommit(String login, long transactionId) 1210 throws SQLException 1211 { 1212 try 1213 { 1214 List groupMembers = dvdb.getAllMembers(); 1215 AbstractRequest commitRequest = new UnknownWriteRequest("commit", false, 1216 0, "\n"); 1217 commitRequest.setTransactionId(transactionId); 1218 commitRequest.setLogin(login); 1219 commitRequest.setIsAutoCommit(false); 1220 1221 MulticastResponse responses = multicastRequest(commitRequest, 1222 new DistributedCommit(login, transactionId), dvdb 1223 .getMessageTimeouts().getCommitTimeout(), groupMembers); 1224 1225 if (logger.isDebugEnabled()) 1226 logger.debug("Commit of transaction " + transactionId + " completed."); 1227 1228 ArrayList failedOnAllBackends = null; 1230 ArrayList controllersWithoutBackends = null; 1232 SQLException exception = null; 1233 groupMembers = dvdb.getAllMembers(); 1235 int size = groupMembers.size(); 1236 boolean success = false; 1237 for (int i = 0; i < size; i++) 1239 { 1240 Member member = (Member) groupMembers.get(i); 1241 if ((responses.getFailedMembers() != null) 1242 && responses.getFailedMembers().contains(member)) 1243 { 1244 logger.warn("Controller " + member + " is suspected of failure."); 1245 continue; 1246 } 1247 Object r = responses.getResult(member); 1248 if (r instanceof Boolean ) 1249 { 1250 if (((Boolean ) r).booleanValue()) 1251 success = true; 1252 else 1253 logger.error("Unexpected result for controller " + member); 1254 } 1255 else if (r instanceof NoMoreBackendException) 1256 { 1257 if (controllersWithoutBackends == null) 1258 controllersWithoutBackends = new ArrayList (); 1259 controllersWithoutBackends.add(member); 1260 if (logger.isDebugEnabled()) 1261 logger.debug("Controller " + member 1262 + " has no more backends to commit transaction " 1263 + transactionId + " (" + r + ")"); 1264 } 1265 else if (r instanceof AllBackendsFailedException) 1266 { 1267 if (failedOnAllBackends == null) 1268 failedOnAllBackends = new ArrayList (); 1269 failedOnAllBackends.add(member); 1270 if (logger.isDebugEnabled()) 1271 logger.debug("Commit failed on all backends of controller " 1272 + member + " (" + r + ")"); 1273 } 1274 else if (r instanceof SQLException ) 1275 { 1276 if (failedOnAllBackends == null) 1277 failedOnAllBackends = new ArrayList (); 1278 failedOnAllBackends.add(member); 1279 String msg = "Commit of transaction " + transactionId 1280 + " failed on controller " + member + " (" + r + ")"; 1281 logger.warn(msg); 1282 exception = (SQLException ) r; 1283 } 1284 } 1285 1286 notifyRequestCompletion(commitRequest, success, true, failedOnAllBackends); 1289 1290 notifyRequestCompletion(commitRequest, success, false, 1292 controllersWithoutBackends); 1293 1294 if (success) 1295 return; 1297 1299 if (exception != null) 1300 throw exception; 1301 else 1302 { 1303 String msg = "Transaction " + transactionId 1304 + " failed to commit on all controllers"; 1305 logger.warn(msg); 1306 throw new SQLException (msg); 1307 } 1308 } 1309 catch (SQLException e) 1310 { 1311 String msg = "Transaction " + transactionId + " commit failed (" + e 1312 + ")"; 1313 logger.warn(msg); 1314 throw e; 1315 } 1316 } 1317 1318 1322 public void distributedRollback(String login, long transactionId) 1323 throws SQLException 1324 { 1325 try 1326 { 1327 List groupMembers = dvdb.getAllMembers(); 1328 1329 AbstractRequest rollbackRequest = new UnknownWriteRequest("rollback", 1330 false, 0, "\n"); 1331 rollbackRequest.setTransactionId(transactionId); 1332 rollbackRequest.setLogin(login); 1333 rollbackRequest.setIsAutoCommit(false); 1334 1335 MulticastResponse responses = multicastRequest(rollbackRequest, 1336 new DistributedRollback(login, transactionId), dvdb 1337 .getMessageTimeouts().getRollbackTimeout(), groupMembers); 1338 1339 if (logger.isDebugEnabled()) 1340 logger 1341 .debug("Rollback of transaction " + transactionId + " completed."); 1342 1343 ArrayList failedOnAllBackends = null; 1345 ArrayList controllersWithoutBackends = null; 1347 SQLException exception = null; 1348 1349 groupMembers = dvdb.getAllMembers(); 1351 int size = groupMembers.size(); 1352 boolean success = false; 1353 for (int i = 0; i < size; i++) 1355 { 1356 Member member = (Member) groupMembers.get(i); 1357 if ((responses.getFailedMembers() != null) 1358 && responses.getFailedMembers().contains(member)) 1359 { 1360 logger.warn("Controller " + member + " is suspected of failure."); 1361 continue; 1362 } 1363 Object r = responses.getResult(member); 1364 if (r instanceof Boolean ) 1365 { 1366 if (((Boolean ) r).booleanValue()) 1367 success = true; 1368 else 1369 logger.error("Unexpected result for controller " + member); 1370 } 1371 else if (r instanceof NoMoreBackendException) 1372 { 1373 if (controllersWithoutBackends == null) 1374 controllersWithoutBackends = new ArrayList (); 1375 controllersWithoutBackends.add(member); 1376 if (logger.isDebugEnabled()) 1377 logger.debug("Controller " + member 1378 + " has no more backends to rollback transaction " 1379 + transactionId + " (" + r + ")"); 1380 } 1381 else if (r instanceof AllBackendsFailedException) 1382 { 1383 if (failedOnAllBackends == null) 1384 failedOnAllBackends = new ArrayList (); 1385 failedOnAllBackends.add(member); 1386 if (logger.isDebugEnabled()) 1387 logger.debug("Rollback failed on all backends of controller " 1388 + member + " (" + r + ")"); 1389 } 1390 else if (r instanceof SQLException ) 1391 { 1392 if (failedOnAllBackends == null) 1393 failedOnAllBackends = new ArrayList (); 1394 failedOnAllBackends.add(member); 1395 String msg = "Rollback of transaction " + transactionId 1396 + " failed on controller " + member + " (" + r + ")"; 1397 logger.warn(msg); 1398 exception = (SQLException ) r; 1399 } 1400 } 1401 1402 notifyRequestCompletion(rollbackRequest, success, true, 1405 failedOnAllBackends); 1406 1407 notifyRequestCompletion(rollbackRequest, success, false, 1409 controllersWithoutBackends); 1410 1411 if (success) 1412 return; 1414 if (exception != null) 1415 throw exception; 1416 1417 1419 String msg = "Transaction " + transactionId 1420 + " failed to rollback on all controllers"; 1421 logger.warn(msg); 1422 throw new SQLException (msg); 1423 } 1424 catch (SQLException e) 1425 { 1426 String msg = "Transaction " + transactionId + " rollback failed (" + e 1427 + ")"; 1428 logger.warn(msg); 1429 throw e; 1430 } 1431 } 1432 1433 1437 public void distributedRollback(String login, long transactionId, 1438 String savepointName) throws SQLException 1439 { 1440 try 1441 { 1442 List groupMembers = dvdb.getAllMembers(); 1443 1444 AbstractRequest rollbackRequest = new UnknownWriteRequest("rollback " 1445 + savepointName, false, 0, "\n"); 1446 rollbackRequest.setTransactionId(transactionId); 1447 rollbackRequest.setLogin(login); 1448 rollbackRequest.setIsAutoCommit(false); 1449 1450 MulticastResponse responses = multicastRequest(rollbackRequest, 1451 new DistributedRollbackToSavepoint(transactionId, savepointName), 1452 dvdb.getMessageTimeouts().getRollbackToSavepointTimeout(), 1453 groupMembers); 1454 1455 if (logger.isDebugEnabled()) 1456 logger.debug("Rollback to savepoint " + savepointName + " for " 1457 + "transaction " + transactionId + " completed."); 1458 1459 ArrayList failedOnAllBackends = null; 1461 ArrayList controllersWithoutBackends = null; 1463 SQLException exception = null; 1464 1465 groupMembers = dvdb.getAllMembers(); 1467 int size = groupMembers.size(); 1468 boolean success = false; 1469 for (int i = 0; i < size; i++) 1471 { 1472 Member member = (Member) groupMembers.get(i); 1473 if ((responses.getFailedMembers() != null) 1474 && responses.getFailedMembers().contains(member)) 1475 { 1476 logger.warn("Controller " + member + " is suspected of failure."); 1477 continue; 1478 } 1479 Object r = responses.getResult(member); 1480 if (r instanceof Boolean ) 1481 { 1482 if (((Boolean ) r).booleanValue()) 1483 success = true; 1484 else 1485 logger.error("Unexpected result for controller " + member); 1486 } 1487 else if (r instanceof NoMoreBackendException) 1488 { 1489 if (controllersWithoutBackends == null) 1490 controllersWithoutBackends = new ArrayList (); 1491 controllersWithoutBackends.add(member); 1492 if (logger.isDebugEnabled()) 1493 logger.debug("Controller " + member + " has no more backends to " 1494 + "rollback to savepoint " + savepointName + " for " 1495 + "transaction " + transactionId + " (" + r + ")"); 1496 } 1497 else if (r instanceof AllBackendsFailedException) 1498 { 1499 if (failedOnAllBackends == null) 1500 failedOnAllBackends = new ArrayList (); 1501 failedOnAllBackends.add(member); 1502 if (logger.isDebugEnabled()) 1503 logger.debug("rollback to savepoint failed on all backends of " 1504 + "controller " + member + " (" + r + ")"); 1505 } 1506 else if (r instanceof SQLException ) 1507 { 1508 if (failedOnAllBackends == null) 1509 failedOnAllBackends = new ArrayList (); 1510 failedOnAllBackends.add(member); 1511 String msg = "rollback to savepoint " + savepointName + " for " 1512 + "transaction " + transactionId + " failed on controller " 1513 + member + " (" + r + ")"; 1514 logger.warn(msg); 1515 exception = (SQLException ) r; 1516 } 1517 } 1518 1519 notifyRequestCompletion(rollbackRequest, success, true, 1522 failedOnAllBackends); 1523 1524 notifyRequestCompletion(rollbackRequest, success, false, 1526 controllersWithoutBackends); 1527 1528 if (success) 1529 return; 1531 if (exception != null) 1532 throw exception; 1533 1534 1536 if (exception != null) 1537 throw exception; 1538 else 1539 { 1540 String msg = "Rollback to savepoint " + savepointName + " for " 1541 + "transaction " + transactionId + " failed on all controllers"; 1542 logger.warn(msg); 1543 throw new SQLException (msg); 1544 } 1545 } 1546 catch (SQLException e) 1547 { 1548 String msg = "Rollback to savepoint " + savepointName + " for " 1549 + "transaction " + transactionId + " failed (" + e + ")"; 1550 logger.warn(msg); 1551 throw e; 1552 } 1553 } 1554 1555 1559 public void distributedSetSavepoint(String login, long transactionId, 1560 String name) throws SQLException 1561 { 1562 try 1563 { 1564 List groupMembers = dvdb.getAllMembers(); 1565 1566 AbstractRequest setSavepointRequest = new UnknownWriteRequest( 1567 "savepoint " + name, false, 0, "\n"); 1568 setSavepointRequest.setTransactionId(transactionId); 1569 setSavepointRequest.setLogin(login); 1570 setSavepointRequest.setIsAutoCommit(false); 1571 1572 MulticastResponse responses = multicastRequest(setSavepointRequest, 1573 new DistributedSetSavepoint(login, transactionId, name), dvdb 1574 .getMessageTimeouts().getSetSavepointTimeout(), groupMembers); 1575 1576 if (logger.isDebugEnabled()) 1577 logger.debug("Set savepoint " + name + " to transaction " 1578 + transactionId + " completed."); 1579 1580 ArrayList failedOnAllBackends = null; 1582 ArrayList controllersWithoutBackends = null; 1584 SQLException exception = null; 1585 1586 groupMembers = dvdb.getAllMembers(); 1588 int size = groupMembers.size(); 1589 boolean success = false; 1590 for (int i = 0; i < size; i++) 1592 { 1593 Member member = (Member) groupMembers.get(i); 1594 if ((responses.getFailedMembers() != null) 1595 && responses.getFailedMembers().contains(member)) 1596 { 1597 logger.warn("Controller " + member + " is suspected of failure."); 1598 continue; 1599 } 1600 Object r = responses.getResult(member); 1601 if (r instanceof Boolean ) 1602 { 1603 if (((Boolean ) r).booleanValue()) 1604 success = true; 1605 else 1606 logger.error("Unexpected result for controller " + member); 1607 } 1608 else if (r instanceof NoMoreBackendException) 1609 { 1610 if (controllersWithoutBackends == null) 1611 controllersWithoutBackends = new ArrayList (); 1612 controllersWithoutBackends.add(member); 1613 if (logger.isDebugEnabled()) 1614 logger.debug("Controller " + member + " has no more backends to " 1615 + "set savepoint " + name + " to transaction " + transactionId 1616 + " (" + r + ")"); 1617 } 1618 else if (r instanceof AllBackendsFailedException) 1619 { 1620 if (failedOnAllBackends == null) 1621 failedOnAllBackends = new ArrayList (); 1622 failedOnAllBackends.add(member); 1623 if (logger.isDebugEnabled()) 1624 logger.debug("set savepoint failed on all backends of controller " 1625 + member + " (" + r + ")"); 1626 } 1627 else if (r instanceof SQLException ) 1628 { 1629 if (failedOnAllBackends == null) 1630 failedOnAllBackends = new ArrayList (); 1631 failedOnAllBackends.add(member); 1632 String msg = "set savepoint " + name + " to transaction " 1633 + transactionId + " failed on controller " + member + " (" + r 1634 + ")"; 1635 logger.warn(msg); 1636 exception = (SQLException ) r; 1637 } 1638 } 1639 1640 notifyRequestCompletion(setSavepointRequest, success, true, 1643 failedOnAllBackends); 1644 1645 notifyRequestCompletion(setSavepointRequest, success, false, 1647 controllersWithoutBackends); 1648 1649 if (success) 1650 return; 1652 if (exception != null) 1653 throw exception; 1654 1655 1657 if (exception != null) 1658 throw exception; 1659 else 1660 { 1661 String msg = "Set savepoint " + name + " to transaction " 1662 + transactionId + " failed on all controllers"; 1663 logger.warn(msg); 1664 throw new SQLException (msg); 1665 } 1666 } 1667 catch (SQLException e) 1668 { 1669 String msg = "Set savepoint " + name + " to transaction " + transactionId 1670 + " failed (" + e + ")"; 1671 logger.warn(msg); 1672 throw e; 1673 } 1674 } 1675 1676 1680 public void distributedReleaseSavepoint(String login, long transactionId, 1681 String name) throws SQLException 1682 { 1683 try 1684 { 1685 List groupMembers = dvdb.getAllMembers(); 1686 1687 AbstractRequest releaseSavepointRequest = new UnknownWriteRequest( 1688 "release " + name, false, 0, "\n"); 1689 releaseSavepointRequest.setTransactionId(transactionId); 1690 releaseSavepointRequest.setLogin(login); 1691 releaseSavepointRequest.setIsAutoCommit(false); 1692 1693 MulticastResponse responses = multicastRequest(releaseSavepointRequest, 1694 new DistributedReleaseSavepoint(transactionId, name), dvdb 1695 .getMessageTimeouts().getReleaseSavepointTimeout(), groupMembers); 1696 1697 if (logger.isDebugEnabled()) 1698 logger.debug("Release savepoint " + name + " from transaction " 1699 + transactionId + " completed."); 1700 1701 ArrayList failedOnAllBackends = null; 1703 ArrayList controllersWithoutBackends = null; 1705 SQLException exception = null; 1706 1707 groupMembers = dvdb.getAllMembers(); 1709 int size = groupMembers.size(); 1710 boolean success = false; 1711 for (int i = 0; i < size; i++) 1713 { 1714 Member member = (Member) groupMembers.get(i); 1715 if ((responses.getFailedMembers() != null) 1716 && responses.getFailedMembers().contains(member)) 1717 { 1718 logger.warn("Controller " + member + " is suspected of failure."); 1719 continue; 1720 } 1721 Object r = responses.getResult(member); 1722 if (r instanceof Boolean ) 1723 { 1724 if (((Boolean ) r).booleanValue()) 1725 success = true; 1726 else 1727 logger.error("Unexpected result for controller " + member); 1728 } 1729 else if (r instanceof NoMoreBackendException) 1730 { 1731 if (controllersWithoutBackends == null) 1732 controllersWithoutBackends = new ArrayList (); 1733 controllersWithoutBackends.add(member); 1734 if (logger.isDebugEnabled()) 1735 logger.debug("Controller " + member + " has no more backends to " 1736 + "release savepoint " + name + " from transaction " 1737 + transactionId + " (" + r + ")"); 1738 } 1739 else if (r instanceof AllBackendsFailedException) 1740 { 1741 if (failedOnAllBackends == null) 1742 failedOnAllBackends = new ArrayList (); 1743 failedOnAllBackends.add(member); 1744 if (logger.isDebugEnabled()) 1745 logger.debug("release savepoint failed on all backends of " 1746 + "controller " + member + " (" + r + ")"); 1747 } 1748 else if (r instanceof SQLException ) 1749 { 1750 if (failedOnAllBackends == null) 1751 failedOnAllBackends = new ArrayList (); 1752 failedOnAllBackends.add(member); 1753 String msg = "release savepoint " + name + " from transaction " 1754 + transactionId + " failed on controller " + member + " (" + r 1755 + ")"; 1756 logger.warn(msg); 1757 exception = (SQLException ) r; 1758 } 1759 } 1760 1761 notifyRequestCompletion(releaseSavepointRequest, success, true, 1764 failedOnAllBackends); 1765 1766 notifyRequestCompletion(releaseSavepointRequest, success, false, 1768 controllersWithoutBackends); 1769 1770 if (success) 1771 return; 1773 if (exception != null) 1774 throw exception; 1775 1776 1778 if (exception != null) 1779 throw exception; 1780 else 1781 { 1782 String msg = "Release savepoint " + name + " from transaction " 1783 + transactionId + " failed on all controllers"; 1784 logger.warn(msg); 1785 throw new SQLException (msg); 1786 } 1787 } 1788 catch (SQLException e) 1789 { 1790 String msg = "Release savepoint " + name + " from transaction " 1791 + transactionId + " failed (" + e + ")"; 1792 logger.warn(msg); 1793 throw e; 1794 } 1795 } 1796 1797} | Popular Tags |