1 22 23 package org.continuent.sequoia.controller.requestmanager.distributed; 24 25 import java.io.Serializable ; 26 import java.sql.SQLException ; 27 import java.util.ArrayList ; 28 import java.util.Iterator ; 29 import java.util.List ; 30 31 import javax.management.NotCompliantMBeanException ; 32 33 import org.continuent.hedera.adapters.MulticastRequestAdapter; 34 import org.continuent.hedera.adapters.MulticastResponse; 35 import org.continuent.hedera.common.Member; 36 import org.continuent.sequoia.common.exceptions.NoMoreBackendException; 37 import org.continuent.sequoia.common.exceptions.NoResultAvailableException; 38 import org.continuent.sequoia.common.i18n.Translate; 39 import org.continuent.sequoia.controller.backend.result.ControllerResultSet; 40 import org.continuent.sequoia.controller.backend.result.ExecuteResult; 41 import org.continuent.sequoia.controller.backend.result.ExecuteUpdateResult; 42 import org.continuent.sequoia.controller.backend.result.GeneratedKeysResult; 43 import org.continuent.sequoia.controller.cache.result.AbstractResultCache; 44 import org.continuent.sequoia.controller.loadbalancer.AbstractLoadBalancer; 45 import org.continuent.sequoia.controller.loadbalancer.AllBackendsFailedException; 46 import org.continuent.sequoia.controller.recoverylog.RecoveryLog; 47 import org.continuent.sequoia.controller.requests.AbstractRequest; 48 import org.continuent.sequoia.controller.requests.AbstractWriteRequest; 49 import org.continuent.sequoia.controller.requests.SelectRequest; 50 import org.continuent.sequoia.controller.requests.StoredProcedure; 51 import org.continuent.sequoia.controller.requests.StoredProcedureCallResult; 52 import org.continuent.sequoia.controller.requests.UnknownWriteRequest; 53 import org.continuent.sequoia.controller.scheduler.AbstractScheduler; 54 import org.continuent.sequoia.controller.virtualdatabase.DistributedVirtualDatabase; 55 import org.continuent.sequoia.controller.virtualdatabase.protocol.DistributedAbort; 56 import org.continuent.sequoia.controller.virtualdatabase.protocol.DistributedCallableStatementExecute; 57 import org.continuent.sequoia.controller.virtualdatabase.protocol.DistributedCallableStatementExecuteQuery; 58 import org.continuent.sequoia.controller.virtualdatabase.protocol.DistributedCallableStatementExecuteUpdate; 59 import org.continuent.sequoia.controller.virtualdatabase.protocol.DistributedCommit; 60 import org.continuent.sequoia.controller.virtualdatabase.protocol.DistributedReleaseSavepoint; 61 import org.continuent.sequoia.controller.virtualdatabase.protocol.DistributedRequest; 62 import org.continuent.sequoia.controller.virtualdatabase.protocol.DistributedRollback; 63 import org.continuent.sequoia.controller.virtualdatabase.protocol.DistributedRollbackToSavepoint; 64 import org.continuent.sequoia.controller.virtualdatabase.protocol.DistributedSetSavepoint; 65 import org.continuent.sequoia.controller.virtualdatabase.protocol.DistributedStatementExecute; 66 import org.continuent.sequoia.controller.virtualdatabase.protocol.DistributedStatementExecuteQuery; 67 import org.continuent.sequoia.controller.virtualdatabase.protocol.DistributedStatementExecuteUpdate; 68 import org.continuent.sequoia.controller.virtualdatabase.protocol.DistributedStatementExecuteUpdateWithKeys; 69 import org.continuent.sequoia.controller.virtualdatabase.protocol.ExecRemoteStatementExecuteQuery; 70 import org.continuent.sequoia.controller.virtualdatabase.protocol.MessageTimeouts; 71 72 81 public class RAIDb2DistributedRequestManager extends DistributedRequestManager 82 { 83 84 98 public RAIDb2DistributedRequestManager(DistributedVirtualDatabase vdb, 99 AbstractScheduler scheduler, AbstractResultCache cache, 100 AbstractLoadBalancer loadBalancer, RecoveryLog recoveryLog, 101 long beginTimeout, long commitTimeout, long rollbackTimeout) 102 throws SQLException , NotCompliantMBeanException 103 { 104 super(vdb, scheduler, cache, loadBalancer, recoveryLog, beginTimeout, 105 commitTimeout, rollbackTimeout); 106 } 107 108 111 public ControllerResultSet distributedStatementExecuteQuery( 112 SelectRequest request) throws SQLException 113 { 114 return executeRequestReturningResultSet(request, 115 new DistributedStatementExecuteQuery(request), dvdb 116 .getMessageTimeouts().getExecReadRequestTimeout()); 117 } 118 119 122 public ControllerResultSet execRemoteStatementExecuteQuery( 123 SelectRequest request) throws SQLException 124 { 125 if (dvdb.isProcessMacroBeforeBroadcast()) 126 loadBalancer.handleMacros(request); 127 try 128 { 129 Iterator i = dvdb.getAllMemberButUs().iterator(); 134 SQLException error = null; 135 while (i.hasNext()) 136 { 137 Member controller = (Member) i.next(); 138 List groupMembers = new ArrayList (); 139 groupMembers.add(controller); 140 141 if (logger.isDebugEnabled()) 142 logger.debug("Sending request " 143 + request.getSqlShortForm(dvdb.getSqlShortFormLength()) 144 + (request.isAutoCommit() ? "" : " transaction " 145 + request.getTransactionId()) + " to " + controller); 146 147 MulticastResponse responses; 149 responses = dvdb.getMulticastRequestAdapter().multicastMessage( 150 groupMembers, 151 new ExecRemoteStatementExecuteQuery(request), 152 MulticastRequestAdapter.WAIT_ALL, 153 MessageTimeouts.getMinTimeout(dvdb.getMessageTimeouts() 154 .getExecReadRequestTimeout(), request.getTimeout() * 1000L)); 155 156 if (logger.isDebugEnabled()) 157 logger.debug("Request " 158 + request.getSqlShortForm(dvdb.getSqlShortFormLength()) 159 + " completed."); 160 161 Object ret = responses.getResult(controller); 162 if (ret instanceof ControllerResultSet) 163 return (ControllerResultSet) ret; 164 else if (ret instanceof SQLException ) 165 error = (SQLException ) ret; 166 } 167 168 if (error == null) 169 { 170 throw new NoMoreBackendException(); 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 notifyRequestCompletion(proc, success, true, failedOnAllBackends); 388 389 notifyRequestCompletion(proc, success, false, 391 controllersWithoutBackends); 392 } 393 394 if (requestResult != null) 395 { 396 if (logger.isDebugEnabled()) 397 logger.debug("Request " + request.getId() 398 + " completed successfully."); 399 return requestResult; 400 } 401 402 404 if (exception != null) 405 throw exception; 406 else 407 { 408 String msg = "Request '" 409 + request.getSqlShortForm(vdb.getSqlShortFormLength()) 410 + "' failed on all controllers"; 411 logger.warn(msg); 412 throw new SQLException (msg); 413 } 414 } 415 catch (SQLException e) 416 { 417 String msg = Translate 418 .get("loadbalancer.request.failed", new String []{ 419 request.getSqlShortForm(vdb.getSqlShortFormLength()), 420 e.getMessage()}); 421 logger.warn(msg); 422 throw e; 423 } 424 } 425 426 435 private GeneratedKeysResult executeRequestReturningGeneratedKeys( 436 AbstractRequest request, DistributedRequest requestMsg, 437 long messageTimeout) throws SQLException 438 { 439 if (dvdb.isProcessMacroBeforeBroadcast()) 440 loadBalancer.handleMacros(request); 441 try 442 { 443 GeneratedKeysResult requestResult = null; 444 445 List groupMembers = dvdb.getAllMembers(); 446 447 MulticastResponse responses = multicastRequest(request, requestMsg, 448 messageTimeout, groupMembers); 449 450 ArrayList failedOnAllBackends = null; 452 ArrayList inconsistentControllers = null; 454 ArrayList controllersWithoutBackends = null; 456 SQLException exception = null; 457 List successfulControllers = null; 458 int size = groupMembers.size(); 459 for (int i = 0; i < size; i++) 461 { 462 Member member = (Member) groupMembers.get(i); 463 if ((responses.getFailedMembers() != null) 464 && responses.getFailedMembers().contains(member)) 465 { 466 logger.warn("Controller " + member + " is suspected of failure."); 467 continue; 468 } 469 Object r = responses.getResult(member); 470 if (r instanceof GeneratedKeysResult) 471 { 472 if (requestResult == null) 473 { 474 requestResult = (GeneratedKeysResult) r; 475 } 476 else 477 { 478 if (requestResult.getUpdateCount() != ((GeneratedKeysResult) r) 479 .getUpdateCount()) 480 { 481 if (inconsistentControllers == null) 482 inconsistentControllers = new ArrayList (); 483 inconsistentControllers.add(member); 484 logger 485 .error("Controller " + member 486 + " returned an inconsistent results (" + requestResult 487 + " when expecting " + r + ") for request " 488 + request.getId()); 489 } 490 } 491 } 492 else if (DistributedRequestManager.SUCCESSFUL_COMPLETION.equals(r)) 493 { 494 if (requestResult == null) 496 { 497 if (successfulControllers == null) 498 successfulControllers = new ArrayList (); 499 successfulControllers.add(member); 500 } 501 } 502 else if (r instanceof NoMoreBackendException) 503 { 504 if (controllersWithoutBackends == null) 505 controllersWithoutBackends = new ArrayList (); 506 controllersWithoutBackends.add(member); 507 if (logger.isDebugEnabled()) 508 logger.debug("Controller " + member 509 + " has no more backends to execute query (" + r + ")"); 510 } 511 else if (r instanceof Exception ) 512 { 513 if (failedOnAllBackends == null) 514 failedOnAllBackends = new ArrayList (); 515 failedOnAllBackends.add(member); 516 String msg = "Request " + request.getId() + " failed on controller " 517 + member + " (" + r + ")"; 518 logger.warn(msg); 519 if (r instanceof SQLException ) 520 exception = (SQLException ) r; 521 else 522 { 523 exception = new SQLException ("Internal exception " + r); 524 exception.initCause((Throwable ) r); 525 } 526 } 527 else 528 { 529 if (failedOnAllBackends == null) 530 failedOnAllBackends = new ArrayList (); 531 failedOnAllBackends.add(member); 532 if (logger.isWarnEnabled()) 533 logger.warn("Unexpected answer from controller " + member + " (" 534 + r + ") for request " 535 + request.getSqlShortForm(vdb.getSqlShortFormLength())); 536 } 537 } 538 539 if ((requestResult == null) && (successfulControllers != null)) 540 { try 543 { 544 requestResult = (GeneratedKeysResult) getRequestResultFromFailoverCache( 545 successfulControllers, request.getId()); 546 } 547 catch (NoResultAvailableException e) 548 { 549 exception = new SQLException ( 550 "Request '" 551 + request 552 + "' was successfully executed on remote controllers, but all successful controllers failed before retrieving result"); 553 } 554 } 555 556 562 boolean success = (requestResult != null || successfulControllers != null); 563 notifyRequestCompletion(request, success, true, failedOnAllBackends); 564 565 notifyRequestCompletion(request, success, false, 567 controllersWithoutBackends); 568 569 if (inconsistentControllers != null) 570 { notifyControllerInconsistency(request, inconsistentControllers); 572 } 573 574 if (requestResult != null) 575 { 576 if (logger.isDebugEnabled()) 577 logger.debug("Request " + request.getId() 578 + " completed successfully."); 579 return requestResult; 580 } 581 582 584 if (exception != null) 585 throw exception; 586 else 587 { 588 String msg = "Request '" + request + "' failed on all controllers"; 589 logger.warn(msg); 590 throw new SQLException (msg); 591 } 592 } 593 catch (SQLException e) 594 { 595 String msg = Translate 596 .get("loadbalancer.request.failed", new String []{ 597 request.getSqlShortForm(vdb.getSqlShortFormLength()), 598 e.getMessage()}); 599 logger.warn(msg); 600 throw e; 601 } 602 } 603 604 613 private ExecuteUpdateResult executeRequestReturningInt( 614 AbstractRequest request, DistributedRequest requestMsg, 615 long messageTimeout) throws SQLException 616 { 617 if (dvdb.isProcessMacroBeforeBroadcast()) 618 loadBalancer.handleMacros(request); 619 try 620 { 621 ExecuteUpdateResult requestResult = null; 622 623 List groupMembers = dvdb.getAllMembers(); 624 625 MulticastResponse responses = multicastRequest(request, requestMsg, 626 messageTimeout, groupMembers); 627 628 ArrayList failedOnAllBackends = null; 630 ArrayList inconsistentControllers = null; 632 ArrayList controllersWithoutBackends = null; 634 SQLException exception = null; 635 int size = groupMembers.size(); 636 for (int i = 0; i < size; i++) 638 { 639 Member member = (Member) groupMembers.get(i); 640 if ((responses.getFailedMembers() != null) 641 && responses.getFailedMembers().contains(member)) 642 { 643 logger.warn("Controller " + member + " is suspected of failure."); 644 continue; 645 } 646 Object r = responses.getResult(member); 647 if (r instanceof ExecuteUpdateResult) 648 { 649 if (requestResult == null) 650 requestResult = (ExecuteUpdateResult) r; 651 else 652 { 653 if (requestResult.getUpdateCount() != ((ExecuteUpdateResult) r) 654 .getUpdateCount()) 655 { 656 if (inconsistentControllers == null) 657 inconsistentControllers = new ArrayList (); 658 inconsistentControllers.add(member); 659 logger.error("Controller " + member 660 + " returned an inconsistent results (" 661 + requestResult.getUpdateCount() + " when expecting " 662 + ((ExecuteUpdateResult) r).getUpdateCount() 663 + ") for request " + request.getId()); 664 } 665 } 666 } 667 else if (r instanceof NoMoreBackendException) 668 { 669 if (controllersWithoutBackends == null) 670 controllersWithoutBackends = new ArrayList (); 671 controllersWithoutBackends.add(member); 672 if (logger.isDebugEnabled()) 673 logger.debug("Controller " + member 674 + " has no more backends to execute query (" + r + ")"); 675 } 676 else if (r instanceof Exception ) 677 { 678 if (failedOnAllBackends == null) 679 failedOnAllBackends = new ArrayList (); 680 failedOnAllBackends.add(member); 681 String msg = "Request " + request.getId() + " failed on controller " 682 + member + " (" + r + ")"; 683 logger.warn(msg); 684 if (r instanceof SQLException ) 685 exception = (SQLException ) r; 686 else 687 { 688 exception = new SQLException ("Internal exception " + r); 689 exception.initCause((Throwable ) r); 690 } 691 } 692 else 693 { 694 if (failedOnAllBackends == null) 695 failedOnAllBackends = new ArrayList (); 696 failedOnAllBackends.add(member); 697 if (logger.isWarnEnabled()) 698 logger.warn("Unexpected answer from controller " + member + " (" 699 + r + ") for request " 700 + request.getSqlShortForm(vdb.getSqlShortFormLength())); 701 } 702 } 703 704 notifyRequestCompletion(request, requestResult != null, true, 707 failedOnAllBackends); 708 709 notifyRequestCompletion(request, requestResult != null, false, 711 controllersWithoutBackends); 712 713 if (inconsistentControllers != null) 714 { notifyControllerInconsistency(request, inconsistentControllers); 716 } 717 718 if (requestResult != null) 719 { 720 if (logger.isDebugEnabled()) 721 logger.debug("Request " + request.getId() 722 + " completed successfully."); 723 return requestResult; 724 } 725 726 728 if (exception != null) 729 throw exception; 730 else 731 { 732 String msg = "Request '" + request + "' failed on all controllers"; 733 logger.warn(msg); 734 throw new SQLException (msg); 735 } 736 } 737 catch (SQLException e) 738 { 739 String msg = Translate 740 .get("loadbalancer.request.failed", new String []{ 741 request.getSqlShortForm(vdb.getSqlShortFormLength()), 742 e.getMessage()}); 743 logger.warn(msg); 744 throw e; 745 } 746 } 747 748 757 private ControllerResultSet executeRequestReturningResultSet( 758 AbstractRequest request, DistributedRequest requestMsg, 759 long messageTimeout) throws SQLException 760 { 761 if (dvdb.isProcessMacroBeforeBroadcast()) 762 loadBalancer.handleMacros(request); 763 try 764 { 765 ControllerResultSet requestResult = null; 766 767 List groupMembers = dvdb.getAllMembers(); 768 769 MulticastResponse responses = multicastRequest(request, requestMsg, 770 messageTimeout, groupMembers); 771 772 ArrayList failedOnAllBackends = null; 774 ArrayList controllersWithoutBackends = null; 776 SQLException exception = null; 777 int size = groupMembers.size(); 778 List successfulControllers = null; 779 for (int i = 0; i < size; i++) 781 { 782 Member member = (Member) groupMembers.get(i); 783 if ((responses.getFailedMembers() != null) 784 && responses.getFailedMembers().contains(member)) 785 { 786 logger.warn("Controller " + member + " is suspected of failure."); 787 continue; 788 } 789 Object r = responses.getResult(member); 790 if (r instanceof ControllerResultSet) 791 { 792 if (requestResult == null) 793 requestResult = (ControllerResultSet) r; 794 } 795 else if (DistributedRequestManager.SUCCESSFUL_COMPLETION.equals(r)) 796 { 797 if (requestResult == null) 799 { 800 if (successfulControllers == null) 801 successfulControllers = new ArrayList (); 802 successfulControllers.add(member); 803 } 804 } 805 else if (r instanceof NoMoreBackendException) 806 { 807 if (controllersWithoutBackends == null) 808 controllersWithoutBackends = new ArrayList (); 809 controllersWithoutBackends.add(member); 810 if (logger.isDebugEnabled()) 811 logger.debug("Controller " + member 812 + " has no more backends to execute query (" + r + ")"); 813 } 814 else if (r instanceof Exception ) 815 { 816 if (failedOnAllBackends == null) 817 failedOnAllBackends = new ArrayList (); 818 failedOnAllBackends.add(member); 819 String msg = "Request " + request.getId() + " failed on controller " 820 + member + " (" + r + ")"; 821 logger.warn(msg); 822 if (r instanceof SQLException ) 823 exception = (SQLException ) r; 824 else 825 { 826 exception = new SQLException ("Internal exception " + r); 827 exception.initCause((Throwable ) r); 828 } 829 } 830 else 831 { 832 if (failedOnAllBackends == null) 833 failedOnAllBackends = new ArrayList (); 834 failedOnAllBackends.add(member); 835 if (logger.isWarnEnabled()) 836 logger.warn("Unexpected answer from controller " + member + " (" 837 + r + ") for request " 838 + request.getSqlShortForm(vdb.getSqlShortFormLength())); 839 } 840 } 841 842 if ((requestResult == null) && (successfulControllers != null)) 843 { try 846 { 847 requestResult = (ControllerResultSet) getRequestResultFromFailoverCache( 848 successfulControllers, request.getId()); 849 } 850 catch (NoResultAvailableException e) 851 { 852 exception = new SQLException ( 853 "Request '" 854 + request 855 + "' was successfully executed on remote controllers, but all successful controllers failed before retrieving result"); 856 } 857 } 858 859 865 boolean success = (requestResult != null || successfulControllers != null); 866 notifyRequestCompletion(request, success, true, failedOnAllBackends); 867 868 notifyRequestCompletion(request, success, false, 870 controllersWithoutBackends); 871 872 if (requestResult != null) 873 { 874 if (logger.isDebugEnabled()) 875 logger.debug("Request " + request.getId() 876 + " completed successfully."); 877 return requestResult; 878 } 879 880 882 if (exception != null) 883 throw exception; 884 else 885 { 886 String msg = "Request '" + request + "' failed on all controllers"; 887 logger.warn(msg); 888 throw new SQLException (msg); 889 } 890 } 891 catch (SQLException e) 892 { 893 String msg = Translate 894 .get("loadbalancer.request.failed", new String []{ 895 request.getSqlShortForm(vdb.getSqlShortFormLength()), 896 e.getMessage()}); 897 logger.warn(msg); 898 throw e; 899 } 900 } 901 902 912 private StoredProcedureCallResult executeRequestReturningStoredProcedureCallResult( 913 StoredProcedure proc, DistributedRequest requestMsg, long messageTimeout) 914 throws SQLException 915 { 916 if (dvdb.isProcessMacroBeforeBroadcast()) 917 loadBalancer.handleMacros(proc); 918 try 919 { 920 StoredProcedureCallResult result = null; 921 922 List groupMembers = dvdb.getAllMembers(); 923 924 MulticastResponse responses = multicastRequest(proc, requestMsg, 925 messageTimeout, groupMembers); 926 927 ArrayList failedOnAllBackends = null; 929 ArrayList controllersWithoutBackends = null; 931 SQLException exception = null; 932 int size = groupMembers.size(); 933 List successfulControllers = null; 934 for (int i = 0; i < size; i++) 936 { 937 Member member = (Member) groupMembers.get(i); 938 if ((responses.getFailedMembers() != null) 939 && responses.getFailedMembers().contains(member)) 940 { 941 logger.warn("Controller " + member + " is suspected of failure."); 942 continue; 943 } 944 Object r = responses.getResult(member); 945 if (r instanceof StoredProcedureCallResult) 946 { 947 if (result == null) 948 result = (StoredProcedureCallResult) r; 949 } 950 else if (DistributedRequestManager.SUCCESSFUL_COMPLETION.equals(r)) 951 { 952 if (result == null) 954 { 955 if (successfulControllers == null) 956 successfulControllers = new ArrayList (); 957 successfulControllers.add(member); 958 } 959 } 960 else if (r instanceof NoMoreBackendException) 961 { 962 if (controllersWithoutBackends == null) 963 controllersWithoutBackends = new ArrayList (); 964 controllersWithoutBackends.add(member); 965 if (logger.isDebugEnabled()) 966 logger.debug("Controller " + member 967 + " has no more backends to execute query (" + r + ")"); 968 } 969 else if (r instanceof Exception ) 970 { 971 if (failedOnAllBackends == null) 972 failedOnAllBackends = new ArrayList (); 973 failedOnAllBackends.add(member); 974 String msg = "Request " + proc.getId() + " failed on controller " 975 + member + " (" + r + ")"; 976 logger.warn(msg); 977 if (r instanceof SQLException ) 978 exception = (SQLException ) r; 979 else 980 { 981 exception = new SQLException ("Internal exception " + r); 982 exception.initCause((Throwable ) r); 983 } 984 } 985 else 986 { 987 if (failedOnAllBackends == null) 988 failedOnAllBackends = new ArrayList (); 989 failedOnAllBackends.add(member); 990 if (logger.isWarnEnabled()) 991 logger.warn("Unexpected answer from controller " + member + " (" 992 + r + ") for request " 993 + proc.getSqlShortForm(vdb.getSqlShortFormLength())); 994 } 995 } 996 997 if ((result == null) && (successfulControllers != null)) 998 { try 1001 { 1002 result = (StoredProcedureCallResult) getRequestResultFromFailoverCache( 1003 successfulControllers, proc.getId()); 1004 } 1005 catch (NoResultAvailableException e) 1006 { 1007 exception = new SQLException ( 1008 "Request '" 1009 + proc 1010 + "' was successfully executed on remote controllers, but all successful controllers failed before retrieving result"); 1011 } 1012 } 1013 1014 1020 boolean success = (result != null || successfulControllers != null); 1021 notifyRequestCompletion(proc, success, true, failedOnAllBackends); 1022 1023 notifyRequestCompletion(proc, success, false, controllersWithoutBackends); 1025 1026 if (result != null) 1027 { 1028 proc.copyNamedAndOutParameters(result.getStoredProcedure()); 1029 if (logger.isDebugEnabled()) 1030 logger.debug("Request " + proc.getId() + " completed successfully."); 1031 return result; 1032 } 1033 1034 1036 if (exception != null) 1037 throw exception; 1038 else 1039 { 1040 String msg = "Request '" + proc + "' failed on all controllers"; 1041 logger.warn(msg); 1042 throw new SQLException (msg); 1043 } 1044 } 1045 catch (SQLException e) 1046 { 1047 String msg = Translate.get("loadbalancer.request.failed", new String []{ 1048 proc.getSqlShortForm(vdb.getSqlShortFormLength()), e.getMessage()}); 1049 logger.warn(msg); 1050 throw e; 1051 } 1052 } 1053 1054 1064 private MulticastResponse multicastRequest(AbstractRequest request, 1065 Serializable requestMsg, long messageTimeout, List groupMembers) 1066 throws SQLException 1067 { 1068 if (logger.isDebugEnabled()) 1069 logger.debug("Broadcasting request " 1070 + request.getSqlShortForm(dvdb.getSqlShortFormLength()) 1071 + (request.isAutoCommit() ? "" : " transaction " 1072 + request.getTransactionId()) + " to all controllers (" 1073 + dvdb.getChannel().getLocalMembership() + "->" 1074 + groupMembers.toString() + ")"); 1075 1076 MulticastResponse responses; 1078 try 1079 { 1080 responses = dvdb.getMulticastRequestAdapter().multicastMessage( 1082 groupMembers, 1083 requestMsg, 1084 MulticastRequestAdapter.WAIT_ALL, 1085 MessageTimeouts.getMinTimeout(messageTimeout, 1086 request.getTimeout() * 1000L)); 1087 } 1088 catch (Exception e) 1089 { 1090 String msg = "An error occured while executing distributed request " 1091 + request.getId(); 1092 logger.warn(msg, e); 1093 throw new SQLException (msg + " (" + e + ")"); 1094 } 1095 1096 if (logger.isDebugEnabled()) 1097 logger.debug("Request " 1098 + request.getSqlShortForm(dvdb.getSqlShortFormLength()) 1099 + " completed."); 1100 1101 if (responses.getFailedMembers() != null) 1102 { logger.warn(responses.getFailedMembers().size() 1104 + " controller(s) died during execution of request " 1105 + request.getId()); 1106 } 1107 return responses; 1108 } 1109 1110 1114 public void distributedAbort(String login, long transactionId) 1115 throws SQLException 1116 { 1117 try 1118 { 1119 List groupMembers = dvdb.getAllMembers(); 1120 1121 AbstractRequest abortRequest = new UnknownWriteRequest("abort", false, 0, 1122 "\n"); 1123 abortRequest.setTransactionId(transactionId); 1124 1125 MulticastResponse responses = multicastRequest(abortRequest, 1126 new DistributedAbort(login, transactionId), dvdb.getMessageTimeouts() 1127 .getRollbackTimeout(), groupMembers); 1128 1129 if (logger.isDebugEnabled()) 1130 logger.debug("Abort of transaction " + transactionId + " completed."); 1131 1132 ArrayList controllersWithoutBackends = null; 1134 SQLException exception = null; 1135 int size = groupMembers.size(); 1136 boolean success = false; 1137 for (int i = 0; i < size; i++) 1139 { 1140 Member member = (Member) groupMembers.get(i); 1141 if ((responses.getFailedMembers() != null) 1142 && responses.getFailedMembers().contains(member)) 1143 { 1144 logger.warn("Controller " + member + " is suspected of failure."); 1145 continue; 1146 } 1147 Object r = responses.getResult(member); 1148 if (r instanceof Boolean ) 1149 { 1150 if (((Boolean ) r).booleanValue()) 1151 success = true; 1152 else 1153 logger.error("Unexpected result for controller " + member); 1154 } 1155 else if (r instanceof NoMoreBackendException) 1156 { 1157 if (controllersWithoutBackends == null) 1158 controllersWithoutBackends = new ArrayList (); 1159 controllersWithoutBackends.add(member); 1160 if (logger.isDebugEnabled()) 1161 logger.debug("Controller " + member 1162 + " has no more backends to abort transaction " 1163 + transactionId + " (" + r + ")"); 1164 } 1165 } 1166 1167 notifyRequestCompletion(abortRequest, success, false, 1169 controllersWithoutBackends); 1170 1171 if (success) 1172 return; 1174 if (exception != null) 1175 throw exception; 1176 1177 1179 String msg = "Transaction " + transactionId 1180 + " failed to abort on all controllers"; 1181 logger.warn(msg); 1182 throw new SQLException (msg); 1183 } 1184 catch (SQLException e) 1185 { 1186 String msg = "Transaction " + transactionId + " abort failed (" + e + ")"; 1187 logger.warn(msg); 1188 throw e; 1189 } 1190 } 1191 1192 1196 public void distributedCommit(String login, long transactionId) 1197 throws SQLException 1198 { 1199 try 1200 { 1201 List groupMembers = dvdb.getAllMembers(); 1202 AbstractRequest commitRequest = new UnknownWriteRequest("commit", false, 1203 0, "\n"); 1204 commitRequest.setTransactionId(transactionId); 1205 commitRequest.setLogin(login); 1206 commitRequest.setIsAutoCommit(false); 1207 1208 MulticastResponse responses = multicastRequest(commitRequest, 1209 new DistributedCommit(login, transactionId), dvdb 1210 .getMessageTimeouts().getCommitTimeout(), groupMembers); 1211 1212 if (logger.isDebugEnabled()) 1213 logger.debug("Commit of transaction " + transactionId + " completed."); 1214 1215 ArrayList failedOnAllBackends = null; 1217 ArrayList controllersWithoutBackends = null; 1219 SQLException exception = null; 1220 groupMembers = dvdb.getAllMembers(); 1222 int size = groupMembers.size(); 1223 boolean success = false; 1224 for (int i = 0; i < size; i++) 1226 { 1227 Member member = (Member) groupMembers.get(i); 1228 if ((responses.getFailedMembers() != null) 1229 && responses.getFailedMembers().contains(member)) 1230 { 1231 logger.warn("Controller " + member + " is suspected of failure."); 1232 continue; 1233 } 1234 Object r = responses.getResult(member); 1235 if (r instanceof Boolean ) 1236 { 1237 if (((Boolean ) r).booleanValue()) 1238 success = true; 1239 else 1240 logger.error("Unexpected result for controller " + member); 1241 } 1242 else if (r instanceof NoMoreBackendException) 1243 { 1244 if (controllersWithoutBackends == null) 1245 controllersWithoutBackends = new ArrayList (); 1246 controllersWithoutBackends.add(member); 1247 if (logger.isDebugEnabled()) 1248 logger.debug("Controller " + member 1249 + " has no more backends to commit transaction " 1250 + transactionId + " (" + r + ")"); 1251 } 1252 else if (r instanceof AllBackendsFailedException) 1253 { 1254 if (failedOnAllBackends == null) 1255 failedOnAllBackends = new ArrayList (); 1256 failedOnAllBackends.add(member); 1257 if (logger.isDebugEnabled()) 1258 logger.debug("Commit failed on all backends of controller " 1259 + member + " (" + r + ")"); 1260 } 1261 else if (r instanceof SQLException ) 1262 { 1263 if (failedOnAllBackends == null) 1264 failedOnAllBackends = new ArrayList (); 1265 failedOnAllBackends.add(member); 1266 String msg = "Commit of transaction " + transactionId 1267 + " failed on controller " + member + " (" + r + ")"; 1268 logger.warn(msg); 1269 exception = (SQLException ) r; 1270 } 1271 } 1272 1273 notifyRequestCompletion(commitRequest, success, true, failedOnAllBackends); 1276 1277 notifyRequestCompletion(commitRequest, success, false, 1279 controllersWithoutBackends); 1280 1281 if (success) 1282 return; 1284 1286 if (exception != null) 1287 throw exception; 1288 else 1289 { 1290 String msg = "Transaction " + transactionId 1291 + " failed to commit on all controllers"; 1292 logger.warn(msg); 1293 throw new SQLException (msg); 1294 } 1295 } 1296 catch (SQLException e) 1297 { 1298 String msg = "Transaction " + transactionId + " commit failed (" + e 1299 + ")"; 1300 logger.warn(msg); 1301 throw e; 1302 } 1303 } 1304 1305 1309 public void distributedRollback(String login, long transactionId) 1310 throws SQLException 1311 { 1312 try 1313 { 1314 List groupMembers = dvdb.getAllMembers(); 1315 1316 AbstractRequest rollbackRequest = new UnknownWriteRequest("rollback", 1317 false, 0, "\n"); 1318 rollbackRequest.setTransactionId(transactionId); 1319 rollbackRequest.setLogin(login); 1320 rollbackRequest.setIsAutoCommit(false); 1321 1322 MulticastResponse responses = multicastRequest(rollbackRequest, 1323 new DistributedRollback(login, transactionId), dvdb 1324 .getMessageTimeouts().getRollbackTimeout(), groupMembers); 1325 1326 if (logger.isDebugEnabled()) 1327 logger 1328 .debug("Rollback of transaction " + transactionId + " completed."); 1329 1330 ArrayList failedOnAllBackends = null; 1332 ArrayList controllersWithoutBackends = null; 1334 SQLException exception = null; 1335 1336 groupMembers = dvdb.getAllMembers(); 1338 int size = groupMembers.size(); 1339 boolean success = false; 1340 for (int i = 0; i < size; i++) 1342 { 1343 Member member = (Member) groupMembers.get(i); 1344 if ((responses.getFailedMembers() != null) 1345 && responses.getFailedMembers().contains(member)) 1346 { 1347 logger.warn("Controller " + member + " is suspected of failure."); 1348 continue; 1349 } 1350 Object r = responses.getResult(member); 1351 if (r instanceof Boolean ) 1352 { 1353 if (((Boolean ) r).booleanValue()) 1354 success = true; 1355 else 1356 logger.error("Unexpected result for controller " + member); 1357 } 1358 else if (r instanceof NoMoreBackendException) 1359 { 1360 if (controllersWithoutBackends == null) 1361 controllersWithoutBackends = new ArrayList (); 1362 controllersWithoutBackends.add(member); 1363 if (logger.isDebugEnabled()) 1364 logger.debug("Controller " + member 1365 + " has no more backends to rollback transaction " 1366 + transactionId + " (" + r + ")"); 1367 } 1368 else if (r instanceof AllBackendsFailedException) 1369 { 1370 if (failedOnAllBackends == null) 1371 failedOnAllBackends = new ArrayList (); 1372 failedOnAllBackends.add(member); 1373 if (logger.isDebugEnabled()) 1374 logger.debug("Rollback failed on all backends of controller " 1375 + member + " (" + r + ")"); 1376 } 1377 else if (r instanceof SQLException ) 1378 { 1379 if (failedOnAllBackends == null) 1380 failedOnAllBackends = new ArrayList (); 1381 failedOnAllBackends.add(member); 1382 String msg = "Rollback of transaction " + transactionId 1383 + " failed on controller " + member + " (" + r + ")"; 1384 logger.warn(msg); 1385 exception = (SQLException ) r; 1386 } 1387 } 1388 1389 notifyRequestCompletion(rollbackRequest, success, true, 1392 failedOnAllBackends); 1393 1394 notifyRequestCompletion(rollbackRequest, success, false, 1396 controllersWithoutBackends); 1397 1398 if (success) 1399 return; 1401 if (exception != null) 1402 throw exception; 1403 1404 1406 String msg = "Transaction " + transactionId 1407 + " failed to rollback on all controllers"; 1408 logger.warn(msg); 1409 throw new SQLException (msg); 1410 } 1411 catch (SQLException e) 1412 { 1413 String msg = "Transaction " + transactionId + " rollback failed (" + e 1414 + ")"; 1415 logger.warn(msg); 1416 throw e; 1417 } 1418 } 1419 1420 1424 public void distributedRollback(String login, long transactionId, 1425 String savepointName) throws SQLException 1426 { 1427 try 1428 { 1429 List groupMembers = dvdb.getAllMembers(); 1430 1431 AbstractRequest rollbackRequest = new UnknownWriteRequest("rollback " 1432 + savepointName, false, 0, "\n"); 1433 rollbackRequest.setTransactionId(transactionId); 1434 rollbackRequest.setLogin(login); 1435 rollbackRequest.setIsAutoCommit(false); 1436 1437 MulticastResponse responses = multicastRequest(rollbackRequest, 1438 new DistributedRollbackToSavepoint(transactionId, savepointName), 1439 dvdb.getMessageTimeouts().getRollbackToSavepointTimeout(), 1440 groupMembers); 1441 1442 if (logger.isDebugEnabled()) 1443 logger.debug("Rollback to savepoint " + savepointName + " for " 1444 + "transaction " + transactionId + " completed."); 1445 1446 ArrayList failedOnAllBackends = null; 1448 ArrayList controllersWithoutBackends = null; 1450 SQLException exception = null; 1451 1452 groupMembers = dvdb.getAllMembers(); 1454 int size = groupMembers.size(); 1455 boolean success = false; 1456 for (int i = 0; i < size; i++) 1458 { 1459 Member member = (Member) groupMembers.get(i); 1460 if ((responses.getFailedMembers() != null) 1461 && responses.getFailedMembers().contains(member)) 1462 { 1463 logger.warn("Controller " + member + " is suspected of failure."); 1464 continue; 1465 } 1466 Object r = responses.getResult(member); 1467 if (r instanceof Boolean ) 1468 { 1469 if (((Boolean ) r).booleanValue()) 1470 success = true; 1471 else 1472 logger.error("Unexpected result for controller " + member); 1473 } 1474 else if (r instanceof NoMoreBackendException) 1475 { 1476 if (controllersWithoutBackends == null) 1477 controllersWithoutBackends = new ArrayList (); 1478 controllersWithoutBackends.add(member); 1479 if (logger.isDebugEnabled()) 1480 logger.debug("Controller " + member + " has no more backends to " 1481 + "rollback to savepoint " + savepointName + " for " 1482 + "transaction " + transactionId + " (" + r + ")"); 1483 } 1484 else if (r instanceof AllBackendsFailedException) 1485 { 1486 if (failedOnAllBackends == null) 1487 failedOnAllBackends = new ArrayList (); 1488 failedOnAllBackends.add(member); 1489 if (logger.isDebugEnabled()) 1490 logger.debug("rollback to savepoint failed on all backends of " 1491 + "controller " + member + " (" + r + ")"); 1492 } 1493 else if (r instanceof SQLException ) 1494 { 1495 if (failedOnAllBackends == null) 1496 failedOnAllBackends = new ArrayList (); 1497 failedOnAllBackends.add(member); 1498 String msg = "rollback to savepoint " + savepointName + " for " 1499 + "transaction " + transactionId + " failed on controller " 1500 + member + " (" + r + ")"; 1501 logger.warn(msg); 1502 exception = (SQLException ) r; 1503 } 1504 } 1505 1506 notifyRequestCompletion(rollbackRequest, success, true, 1509 failedOnAllBackends); 1510 1511 notifyRequestCompletion(rollbackRequest, success, false, 1513 controllersWithoutBackends); 1514 1515 if (success) 1516 return; 1518 if (exception != null) 1519 throw exception; 1520 1521 1523 if (exception != null) 1524 throw exception; 1525 else 1526 { 1527 String msg = "Rollback to savepoint " + savepointName + " for " 1528 + "transaction " + transactionId + " failed on all controllers"; 1529 logger.warn(msg); 1530 throw new SQLException (msg); 1531 } 1532 } 1533 catch (SQLException e) 1534 { 1535 String msg = "Rollback to savepoint " + savepointName + " for " 1536 + "transaction " + transactionId + " failed (" + e + ")"; 1537 logger.warn(msg); 1538 throw e; 1539 } 1540 } 1541 1542 1546 public void distributedSetSavepoint(String login, long transactionId, 1547 String name) throws SQLException 1548 { 1549 try 1550 { 1551 List groupMembers = dvdb.getAllMembers(); 1552 1553 AbstractRequest setSavepointRequest = new UnknownWriteRequest( 1554 "savepoint " + name, false, 0, "\n"); 1555 setSavepointRequest.setTransactionId(transactionId); 1556 setSavepointRequest.setLogin(login); 1557 setSavepointRequest.setIsAutoCommit(false); 1558 1559 MulticastResponse responses = multicastRequest(setSavepointRequest, 1560 new DistributedSetSavepoint(login, transactionId, name), dvdb 1561 .getMessageTimeouts().getSetSavepointTimeout(), groupMembers); 1562 1563 if (logger.isDebugEnabled()) 1564 logger.debug("Set savepoint " + name + " to transaction " 1565 + transactionId + " completed."); 1566 1567 ArrayList failedOnAllBackends = null; 1569 ArrayList controllersWithoutBackends = null; 1571 SQLException exception = null; 1572 1573 groupMembers = dvdb.getAllMembers(); 1575 int size = groupMembers.size(); 1576 boolean success = false; 1577 for (int i = 0; i < size; i++) 1579 { 1580 Member member = (Member) groupMembers.get(i); 1581 if ((responses.getFailedMembers() != null) 1582 && responses.getFailedMembers().contains(member)) 1583 { 1584 logger.warn("Controller " + member + " is suspected of failure."); 1585 continue; 1586 } 1587 Object r = responses.getResult(member); 1588 if (r instanceof Boolean ) 1589 { 1590 if (((Boolean ) r).booleanValue()) 1591 success = true; 1592 else 1593 logger.error("Unexpected result for controller " + member); 1594 } 1595 else if (r instanceof NoMoreBackendException) 1596 { 1597 if (controllersWithoutBackends == null) 1598 controllersWithoutBackends = new ArrayList (); 1599 controllersWithoutBackends.add(member); 1600 if (logger.isDebugEnabled()) 1601 logger.debug("Controller " + member + " has no more backends to " 1602 + "set savepoint " + name + " to transaction " + transactionId 1603 + " (" + r + ")"); 1604 } 1605 else if (r instanceof AllBackendsFailedException) 1606 { 1607 if (failedOnAllBackends == null) 1608 failedOnAllBackends = new ArrayList (); 1609 failedOnAllBackends.add(member); 1610 if (logger.isDebugEnabled()) 1611 logger.debug("set savepoint failed on all backends of controller " 1612 + member + " (" + r + ")"); 1613 } 1614 else if (r instanceof SQLException ) 1615 { 1616 if (failedOnAllBackends == null) 1617 failedOnAllBackends = new ArrayList (); 1618 failedOnAllBackends.add(member); 1619 String msg = "set savepoint " + name + " to transaction " 1620 + transactionId + " failed on controller " + member + " (" + r 1621 + ")"; 1622 logger.warn(msg); 1623 exception = (SQLException ) r; 1624 } 1625 } 1626 1627 notifyRequestCompletion(setSavepointRequest, success, true, 1630 failedOnAllBackends); 1631 1632 notifyRequestCompletion(setSavepointRequest, success, false, 1634 controllersWithoutBackends); 1635 1636 if (success) 1637 return; 1639 if (exception != null) 1640 throw exception; 1641 1642 1644 if (exception != null) 1645 throw exception; 1646 else 1647 { 1648 String msg = "Set savepoint " + name + " to transaction " 1649 + transactionId + " failed on all controllers"; 1650 logger.warn(msg); 1651 throw new SQLException (msg); 1652 } 1653 } 1654 catch (SQLException e) 1655 { 1656 String msg = "Set savepoint " + name + " to transaction " + transactionId 1657 + " failed (" + e + ")"; 1658 logger.warn(msg); 1659 throw e; 1660 } 1661 } 1662 1663 1667 public void distributedReleaseSavepoint(String login, long transactionId, 1668 String name) throws SQLException 1669 { 1670 try 1671 { 1672 List groupMembers = dvdb.getAllMembers(); 1673 1674 AbstractRequest releaseSavepointRequest = new UnknownWriteRequest( 1675 "release " + name, false, 0, "\n"); 1676 releaseSavepointRequest.setTransactionId(transactionId); 1677 releaseSavepointRequest.setLogin(login); 1678 releaseSavepointRequest.setIsAutoCommit(false); 1679 1680 MulticastResponse responses = multicastRequest(releaseSavepointRequest, 1681 new DistributedReleaseSavepoint(transactionId, name), dvdb 1682 .getMessageTimeouts().getReleaseSavepointTimeout(), groupMembers); 1683 1684 if (logger.isDebugEnabled()) 1685 logger.debug("Release savepoint " + name + " from transaction " 1686 + transactionId + " completed."); 1687 1688 ArrayList failedOnAllBackends = null; 1690 ArrayList controllersWithoutBackends = null; 1692 SQLException exception = null; 1693 1694 groupMembers = dvdb.getAllMembers(); 1696 int size = groupMembers.size(); 1697 boolean success = false; 1698 for (int i = 0; i < size; i++) 1700 { 1701 Member member = (Member) groupMembers.get(i); 1702 if ((responses.getFailedMembers() != null) 1703 && responses.getFailedMembers().contains(member)) 1704 { 1705 logger.warn("Controller " + member + " is suspected of failure."); 1706 continue; 1707 } 1708 Object r = responses.getResult(member); 1709 if (r instanceof Boolean ) 1710 { 1711 if (((Boolean ) r).booleanValue()) 1712 success = true; 1713 else 1714 logger.error("Unexpected result for controller " + member); 1715 } 1716 else if (r instanceof NoMoreBackendException) 1717 { 1718 if (controllersWithoutBackends == null) 1719 controllersWithoutBackends = new ArrayList (); 1720 controllersWithoutBackends.add(member); 1721 if (logger.isDebugEnabled()) 1722 logger.debug("Controller " + member + " has no more backends to " 1723 + "release savepoint " + name + " from transaction " 1724 + transactionId + " (" + r + ")"); 1725 } 1726 else if (r instanceof AllBackendsFailedException) 1727 { 1728 if (failedOnAllBackends == null) 1729 failedOnAllBackends = new ArrayList (); 1730 failedOnAllBackends.add(member); 1731 if (logger.isDebugEnabled()) 1732 logger.debug("release savepoint failed on all backends of " 1733 + "controller " + member + " (" + r + ")"); 1734 } 1735 else if (r instanceof SQLException ) 1736 { 1737 if (failedOnAllBackends == null) 1738 failedOnAllBackends = new ArrayList (); 1739 failedOnAllBackends.add(member); 1740 String msg = "release savepoint " + name + " from transaction " 1741 + transactionId + " failed on controller " + member + " (" + r 1742 + ")"; 1743 logger.warn(msg); 1744 exception = (SQLException ) r; 1745 } 1746 } 1747 1748 notifyRequestCompletion(releaseSavepointRequest, success, true, 1751 failedOnAllBackends); 1752 1753 notifyRequestCompletion(releaseSavepointRequest, success, false, 1755 controllersWithoutBackends); 1756 1757 if (success) 1758 return; 1760 if (exception != null) 1761 throw exception; 1762 1763 1765 if (exception != null) 1766 throw exception; 1767 else 1768 { 1769 String msg = "Release savepoint " + name + " from transaction " 1770 + transactionId + " failed on all controllers"; 1771 logger.warn(msg); 1772 throw new SQLException (msg); 1773 } 1774 } 1775 catch (SQLException e) 1776 { 1777 String msg = "Release savepoint " + name + " from transaction " 1778 + transactionId + " failed (" + e + ")"; 1779 logger.warn(msg); 1780 throw e; 1781 } 1782 } 1783 1784} | Popular Tags |