1 24 25 package org.objectweb.cjdbc.controller.requestmanager.distributed; 26 27 import java.sql.SQLException ; 28 import java.util.ArrayList ; 29 import java.util.Iterator ; 30 31 import javax.management.NotCompliantMBeanException ; 32 33 import org.objectweb.cjdbc.common.exceptions.NoMoreBackendException; 34 import org.objectweb.cjdbc.common.i18n.Translate; 35 import org.objectweb.cjdbc.common.sql.AbstractRequest; 36 import org.objectweb.cjdbc.common.sql.AbstractWriteRequest; 37 import org.objectweb.cjdbc.common.sql.SelectRequest; 38 import org.objectweb.cjdbc.common.sql.StoredProcedure; 39 import org.objectweb.cjdbc.common.sql.UnknownRequest; 40 import org.objectweb.cjdbc.controller.cache.result.AbstractResultCache; 41 import org.objectweb.cjdbc.controller.loadbalancer.AbstractLoadBalancer; 42 import org.objectweb.cjdbc.controller.loadbalancer.AllBackendsFailedException; 43 import org.objectweb.cjdbc.controller.recoverylog.RecoveryLog; 44 import org.objectweb.cjdbc.controller.requestmanager.TransactionMarkerMetaData; 45 import org.objectweb.cjdbc.controller.scheduler.AbstractScheduler; 46 import org.objectweb.cjdbc.controller.virtualdatabase.ControllerResultSet; 47 import org.objectweb.cjdbc.controller.virtualdatabase.DistributedVirtualDatabase; 48 import org.objectweb.cjdbc.controller.virtualdatabase.protocol.CJDBCGroupMessage; 49 import org.objectweb.cjdbc.controller.virtualdatabase.protocol.Commit; 50 import org.objectweb.cjdbc.controller.virtualdatabase.protocol.ExecReadRequest; 51 import org.objectweb.cjdbc.controller.virtualdatabase.protocol.ExecReadStoredProcedure; 52 import org.objectweb.cjdbc.controller.virtualdatabase.protocol.ExecWriteRequest; 53 import org.objectweb.cjdbc.controller.virtualdatabase.protocol.ExecWriteRequestWithKeys; 54 import org.objectweb.cjdbc.controller.virtualdatabase.protocol.ExecWriteStoredProcedure; 55 import org.objectweb.cjdbc.controller.virtualdatabase.protocol.NotifyCompletion; 56 import org.objectweb.cjdbc.controller.virtualdatabase.protocol.ReleaseSavepoint; 57 import org.objectweb.cjdbc.controller.virtualdatabase.protocol.Rollback; 58 import org.objectweb.cjdbc.controller.virtualdatabase.protocol.RollbackToSavepoint; 59 import org.objectweb.cjdbc.controller.virtualdatabase.protocol.SetSavepoint; 60 import org.objectweb.cjdbc.controller.virtualdatabase.protocol.UnlogCommit; 61 import org.objectweb.cjdbc.controller.virtualdatabase.protocol.UnlogRequest; 62 import org.objectweb.cjdbc.controller.virtualdatabase.protocol.UnlogRollback; 63 import org.objectweb.tribe.adapters.MulticastRequestAdapter; 64 import org.objectweb.tribe.adapters.MulticastResponse; 65 import org.objectweb.tribe.common.Member; 66 67 75 public class RAIDb1DistributedRequestManager extends DistributedRequestManager 76 { 77 91 public RAIDb1DistributedRequestManager(DistributedVirtualDatabase vdb, 92 AbstractScheduler scheduler, AbstractResultCache cache, 93 AbstractLoadBalancer loadBalancer, RecoveryLog recoveryLog, 94 long beginTimeout, long commitTimeout, long rollbackTimeout) 95 throws SQLException , NotCompliantMBeanException 96 { 97 super(vdb, scheduler, cache, loadBalancer, recoveryLog, beginTimeout, 98 commitTimeout, rollbackTimeout); 99 } 100 101 104 public ControllerResultSet execRemoteReadRequest(SelectRequest request) 105 throws SQLException 106 { 107 try 108 { 109 Iterator i = dvdb.getAllMemberButUs().iterator(); 112 while (i.hasNext()) 113 { 114 Member controller = (Member) i.next(); 115 ArrayList groupMembers = new ArrayList (); 116 groupMembers.add(controller); 117 118 if (logger.isDebugEnabled()) 119 logger.debug("Sending request " 120 + request.getSQLShortForm(dvdb.getSQLShortFormLength()) 121 + (request.isAutoCommit() ? "" : " transaction " 122 + request.getTransactionId()) + " to " + controller); 123 124 MulticastResponse responses; 126 responses = dvdb.getMulticastRequestAdapter().multicastMessage( 127 groupMembers, new ExecReadRequest(request), 128 MulticastRequestAdapter.WAIT_ALL, 129 CJDBCGroupMessage.defaultCastTimeOut); 130 131 if (logger.isDebugEnabled()) 132 logger.debug("Request " 133 + request.getSQLShortForm(dvdb.getSQLShortFormLength()) 134 + " completed."); 135 136 Object ret = responses.getResult(controller); 137 if (ret instanceof ControllerResultSet) 138 return (ControllerResultSet) ret; 139 } 140 141 throw new NoMoreBackendException(); 143 } 144 catch (Exception e) 145 { 146 String msg = "An error occured while executing remote select request " 147 + request.getId(); 148 logger.warn(msg, e); 149 throw new SQLException (msg + " (" + e + ")"); 150 } 151 } 152 153 156 public int execDistributedWriteRequest(AbstractWriteRequest request) 157 throws SQLException 158 { 159 try 160 { 161 int execWriteRequestResult = -1; 162 163 ArrayList groupMembers = dvdb.getCurrentGroup().getMembers(); 164 165 if (logger.isDebugEnabled()) 166 logger.debug("Broadcasting request " 167 + request.getSQLShortForm(dvdb.getSQLShortFormLength()) 168 + (request.isAutoCommit() ? "" : " transaction " 169 + request.getTransactionId()) + " to all controllers (" 170 + dvdb.getChannel().getLocalMembership() + "->" 171 + groupMembers.toString() + ")"); 172 173 MulticastResponse responses; 175 try 176 { 177 responses = dvdb.getMulticastRequestAdapter().multicastMessage( 178 groupMembers, new ExecWriteRequest(request), 179 MulticastRequestAdapter.WAIT_ALL, 180 CJDBCGroupMessage.defaultCastTimeOut); } 183 catch (Exception e) 184 { 185 String msg = "An error occured while executing distributed write request " 186 + request.getId(); 187 logger.warn(msg, e); 188 throw new SQLException (msg + " (" + e + ")"); 189 } 190 191 if (logger.isDebugEnabled()) 192 logger.debug("Request " 193 + request.getSQLShortForm(dvdb.getSQLShortFormLength()) 194 + " completed."); 195 196 if (responses.getFailedMembers() != null) 197 { logger.warn(responses.getFailedMembers().size() 199 + " controller(s) died during execution of request " 200 + request.getId()); 201 } 202 203 ArrayList failedOnAllBackends = null; 205 ArrayList controllersWithoutBackends = null; 207 SQLException exception = null; 208 int size = groupMembers.size(); 209 for (int i = 0; i < size; i++) 211 { 212 Member member = (Member) groupMembers.get(i); 213 if ((responses.getFailedMembers() != null) 214 && responses.getFailedMembers().contains(member)) 215 { 216 logger.warn("Controller " + member + " is suspected of failure."); 217 continue; 218 } 219 Object r = responses.getResult(member); 220 if (r instanceof Integer ) 221 { 222 if (execWriteRequestResult == -1) 223 execWriteRequestResult = ((Integer ) r).intValue(); 224 else if (execWriteRequestResult != ((Integer ) r).intValue()) 225 logger.error("Controllers have different results for request " 226 + request.getId()); 227 } 228 else if (r instanceof AllBackendsFailedException) 229 { 230 if (failedOnAllBackends == null) 231 failedOnAllBackends = new ArrayList (); 232 failedOnAllBackends.add(member); 233 if (logger.isDebugEnabled()) 234 logger.debug("Request failed on all backends of controller " 235 + member + " (" + r + ")"); 236 } 237 else if (r instanceof NoMoreBackendException) 238 { 239 if (controllersWithoutBackends == null) 240 controllersWithoutBackends = new ArrayList (); 241 controllersWithoutBackends.add(member); 242 if (logger.isDebugEnabled()) 243 logger.debug("Controller " + member 244 + " has no more backends to execute query (" + r + ")"); 245 } 246 else if (r instanceof SQLException ) 247 { 248 String msg = "Request " + request.getId() + " failed on controller " 249 + member + " (" + r + ")"; 250 logger.warn(msg); 251 exception = (SQLException ) r; 252 } 253 } 254 255 if (failedOnAllBackends != null) 256 { try 258 { 259 dvdb.getMulticastRequestAdapter().multicastMessage( 260 failedOnAllBackends, 261 new NotifyCompletion(request, execWriteRequestResult != -1), 262 MulticastRequestAdapter.WAIT_NONE, 263 CJDBCGroupMessage.defaultCastTimeOut); } 266 catch (Exception e) 267 { 268 String msg = "An error occured while notifying all controllers of failure of distributed write request " 269 + request.getId(); 270 logger.warn(msg, e); 271 throw new SQLException (msg + " (" + e + ")"); 272 } 273 } 274 275 if (execWriteRequestResult != -1) 276 { 277 if (logger.isDebugEnabled()) 278 logger.debug("Request " + request.getId() 279 + " completed successfully."); 280 return execWriteRequestResult; 281 } 282 283 285 if (controllersWithoutBackends != null) 286 { 289 int nbOfControllers = controllersWithoutBackends.size(); 290 for (int i = 0; i < nbOfControllers; i++) 291 { 292 Member member = (Member) controllersWithoutBackends.get(i); 293 NoMoreBackendException nmbe = (NoMoreBackendException) responses 294 .getResult(member); 295 try 296 { 297 ArrayList dest = new ArrayList (); 298 dest.add(member); 299 dvdb.getMulticastRequestAdapter().multicastMessage(dest, 300 new UnlogRequest(request, nmbe.getRecoveryLogId()), 301 MulticastRequestAdapter.WAIT_NONE, 302 CJDBCGroupMessage.defaultCastTimeOut); } 305 catch (Exception e) 306 { 307 String msg = "An error occured while notifying controllers " 308 + member + " to unlog failed distributed write request " 309 + request.getId(); 310 logger.error(msg, e); 311 } 312 } 313 } 314 315 if (exception != null) 316 throw exception; 317 else 318 { 319 String msg = "Request '" + request + "' failed on all controllers"; 320 logger.warn(msg); 321 throw new SQLException (msg); 322 } 323 } 324 catch (SQLException e) 325 { 326 String msg = Translate 327 .get("loadbalancer.request.failed", new String []{ 328 request.getSQLShortForm(vdb.getSQLShortFormLength()), 329 e.getMessage()}); 330 logger.warn(msg); 331 throw e; 332 } 333 } 334 335 338 public ControllerResultSet execDistributedWriteRequestWithKeys( 339 AbstractWriteRequest request) throws SQLException 340 { 341 try 342 { 343 ControllerResultSet execWriteRequestResult = null; 344 345 ArrayList groupMembers = dvdb.getCurrentGroup().getMembers(); 346 347 if (logger.isDebugEnabled()) 348 logger.debug("Broadcasting request " 349 + request.getSQLShortForm(dvdb.getSQLShortFormLength()) 350 + (request.isAutoCommit() ? "" : " transaction " 351 + request.getTransactionId()) + ") to all controllers (" 352 + dvdb.getChannel().getLocalMembership() + "->" 353 + groupMembers.toString() + ")"); 354 355 MulticastResponse responses; 357 try 358 { 359 responses = dvdb.getMulticastRequestAdapter().multicastMessage( 360 groupMembers, new ExecWriteRequestWithKeys(request), 361 MulticastRequestAdapter.WAIT_ALL, 362 CJDBCGroupMessage.defaultCastTimeOut); } 365 catch (Exception e) 366 { 367 String msg = "An error occured while executing distributed write request with keys " 368 + request.getId(); 369 logger.warn(msg, e); 370 throw new SQLException (msg + " (" + e + ")"); 371 } 372 373 if (logger.isDebugEnabled()) 374 logger.debug("Request " 375 + request.getSQLShortForm(dvdb.getSQLShortFormLength()) 376 + " completed."); 377 378 if (responses.getFailedMembers() != null) 379 { logger.warn(responses.getFailedMembers().size() 381 + " controller(s) died during execution of request " 382 + request.getId()); 383 } 384 385 ArrayList failedOnAllBackends = null; 387 ArrayList controllersWithoutBackends = null; 389 SQLException exception = null; 390 int size = groupMembers.size(); 391 for (int i = 0; i < size; i++) 393 { 394 Member member = (Member) groupMembers.get(i); 395 if ((responses.getFailedMembers() != null) 396 && responses.getFailedMembers().contains(member)) 397 { 398 logger.warn("Controller " + member + " is suspected of failure."); 399 continue; 400 } 401 Object r = responses.getResult(member); 402 if (r instanceof ControllerResultSet) 403 { 404 if (execWriteRequestResult == null) 405 execWriteRequestResult = (ControllerResultSet) r; 406 } 407 else if (r instanceof AllBackendsFailedException) 408 { 409 if (failedOnAllBackends == null) 410 failedOnAllBackends = new ArrayList (); 411 failedOnAllBackends.add(member); 412 if (logger.isDebugEnabled()) 413 logger.debug("Request failed on all backends of controller " 414 + member + " (" + r + ")"); 415 } 416 else if (r instanceof NoMoreBackendException) 417 { 418 if (controllersWithoutBackends == null) 419 controllersWithoutBackends = new ArrayList (); 420 controllersWithoutBackends.add(member); 421 if (logger.isDebugEnabled()) 422 logger.debug("Controller " + member 423 + " has no more backends to execute query (" + r + ")"); 424 } 425 else if (r instanceof SQLException ) 426 { 427 String msg = "Request " + request.getId() + " failed on controller " 428 + member + " (" + r + ")"; 429 logger.warn(msg); 430 exception = (SQLException ) r; 431 } 432 } 433 434 if (failedOnAllBackends != null) 435 { try 437 { 438 dvdb.getMulticastRequestAdapter().multicastMessage( 439 failedOnAllBackends, 440 new NotifyCompletion(request, execWriteRequestResult != null), 441 MulticastRequestAdapter.WAIT_NONE, 442 CJDBCGroupMessage.defaultCastTimeOut); } 445 catch (Exception e) 446 { 447 String msg = "An error occured while notifying all controllers of failure of distributed write request with keys " 448 + request.getId(); 449 logger.warn(msg, e); 450 throw new SQLException (msg + " (" + e + ")"); 451 } 452 } 453 454 if (execWriteRequestResult != null) 455 { 456 if (logger.isDebugEnabled()) 457 logger.debug("Request " + request.getId() 458 + " completed successfully."); 459 return execWriteRequestResult; 460 } 461 462 464 if (controllersWithoutBackends != null) 465 { 468 int nbOfControllers = controllersWithoutBackends.size(); 469 for (int i = 0; i < nbOfControllers; i++) 470 { 471 Member member = (Member) controllersWithoutBackends.get(i); 472 NoMoreBackendException nmbe = (NoMoreBackendException) responses 473 .getResult(member); 474 try 475 { 476 ArrayList dest = new ArrayList (); 477 dest.add(member); 478 dvdb.getMulticastRequestAdapter().multicastMessage(dest, 479 new UnlogRequest(request, nmbe.getRecoveryLogId()), 480 MulticastRequestAdapter.WAIT_NONE, 481 CJDBCGroupMessage.defaultCastTimeOut); 482 } 483 catch (Exception e) 484 { 485 String msg = "An error occured while notifying controllers " 486 + member + " to unlog failed distributed write request " 487 + request.getId(); 488 logger.error(msg, e); 489 } 490 } 491 } 492 493 if (exception != null) 494 throw exception; 495 else 496 { 497 String msg = "Request '" + request + "' failed on all controllers"; 498 logger.warn(msg); 499 throw new SQLException (msg); 500 } 501 } 502 catch (SQLException e) 503 { 504 String msg = Translate 505 .get("loadbalancer.request.failed", new String []{ 506 request.getSQLShortForm(vdb.getSQLShortFormLength()), 507 e.getMessage()}); 508 logger.warn(msg); 509 throw e; 510 } 511 } 512 513 516 public ControllerResultSet execDistributedReadStoredProcedure( 517 StoredProcedure proc) throws SQLException 518 { 519 try 520 { 521 ControllerResultSet result = null; 522 523 ArrayList groupMembers = dvdb.getCurrentGroup().getMembers(); 524 525 if (logger.isDebugEnabled()) 526 logger.debug("Broadcasting read stored procedure " 527 + proc.getSQLShortForm(dvdb.getSQLShortFormLength()) 528 + (proc.isAutoCommit() ? "" : " transaction " 529 + proc.getTransactionId()) + ") to all controllers (" 530 + dvdb.getChannel().getLocalMembership() + "->" 531 + groupMembers.toString() + ")"); 532 533 MulticastResponse responses; 535 try 536 { 537 responses = dvdb.getMulticastRequestAdapter().multicastMessage( 538 groupMembers, new ExecReadStoredProcedure(proc), 539 MulticastRequestAdapter.WAIT_ALL, 540 CJDBCGroupMessage.defaultCastTimeOut); } 542 catch (Exception e) 543 { 544 String msg = "An error occured while executing distributed read stored procedure " 545 + proc.getId(); 546 logger.warn(msg, e); 547 throw new SQLException (msg + " (" + e + ")"); 548 } 549 550 if (logger.isDebugEnabled()) 551 logger.debug("Stored procedure " 552 + proc.getSQLShortForm(dvdb.getSQLShortFormLength()) 553 + " completed."); 554 555 if (responses.getFailedMembers() != null) 556 { logger.warn(responses.getFailedMembers().size() 558 + " controller(s) died during execution of stored procedure " 559 + proc.getId()); 560 } 561 562 ArrayList failedOnAllBackends = null; 564 ArrayList controllersWithoutBackends = null; 566 SQLException exception = null; 567 int size = groupMembers.size(); 568 for (int i = 0; i < size; i++) 570 { 571 Member member = (Member) groupMembers.get(i); 572 if ((responses.getFailedMembers() != null) 573 && responses.getFailedMembers().contains(member)) 574 { 575 logger.warn("Controller " + member + " is suspected of failure."); 576 continue; 577 } 578 Object r = responses.getResult(member); 579 if (r instanceof ControllerResultSet) 580 { 581 if (result == null) 582 result = (ControllerResultSet) r; 583 } 584 else if (r instanceof AllBackendsFailedException) 585 { 586 if (failedOnAllBackends == null) 587 failedOnAllBackends = new ArrayList (); 588 failedOnAllBackends.add(member); 589 } 590 else if (r instanceof NoMoreBackendException) 591 { 592 if (controllersWithoutBackends == null) 593 controllersWithoutBackends = new ArrayList (); 594 controllersWithoutBackends.add(member); 595 if (logger.isDebugEnabled()) 596 logger.debug("Controller " + member 597 + " has no more backends to execute query (" + r + ")"); 598 } 599 else if (r instanceof SQLException ) 600 { 601 String msg = "Stored procedure " + proc.getId() 602 + " failed on controller " + member + " (" + r + ")"; 603 logger.warn(msg); 604 exception = (SQLException ) r; 605 } 606 } 607 608 if (failedOnAllBackends != null) 609 { try 611 { 612 dvdb.getMulticastRequestAdapter().multicastMessage( 613 failedOnAllBackends, new NotifyCompletion(proc, result != null), 614 MulticastRequestAdapter.WAIT_NONE, 615 CJDBCGroupMessage.defaultCastTimeOut); } 618 catch (Exception e) 619 { 620 String msg = "An error occured while notifying all controllers of failure of read stored procedure " 621 + proc.getId(); 622 logger.warn(msg, e); 623 throw new SQLException (msg + " (" + e + ")"); 624 } 625 } 626 627 if (result != null) 628 { 629 if (logger.isDebugEnabled()) 630 logger.debug("Stored procedure " + proc.getId() 631 + " completed successfully."); 632 return result; } 634 635 637 if (controllersWithoutBackends != null) 638 { 641 int nbOfControllers = controllersWithoutBackends.size(); 642 for (int i = 0; i < nbOfControllers; i++) 643 { 644 Member member = (Member) controllersWithoutBackends.get(i); 645 NoMoreBackendException nmbe = (NoMoreBackendException) responses 646 .getResult(member); 647 try 648 { 649 ArrayList dest = new ArrayList (); 650 dest.add(member); 651 dvdb.getMulticastRequestAdapter().multicastMessage(dest, 652 new UnlogRequest(proc, nmbe.getRecoveryLogId()), 653 MulticastRequestAdapter.WAIT_NONE, 654 CJDBCGroupMessage.defaultCastTimeOut); } 657 catch (Exception e) 658 { 659 String msg = "An error occured while notifying controllers " 660 + member 661 + " to unlog failed distributed read stored procedure " 662 + proc.getId(); 663 logger.error(msg, e); 664 } 665 } 666 } 667 668 if (exception != null) 669 throw exception; 670 else 671 { 672 String msg = "Stored procedure '" + proc 673 + "' failed on all controllers"; 674 logger.warn(msg); 675 throw new SQLException (msg); 676 } 677 } 678 catch (SQLException e) 679 { 680 String msg = Translate.get("loadbalancer.request.failed", new String []{ 681 proc.getSQLShortForm(vdb.getSQLShortFormLength()), e.getMessage()}); 682 logger.warn(msg); 683 throw e; 684 } 685 } 686 687 690 public int execDistributedWriteStoredProcedure(StoredProcedure proc) 691 throws SQLException 692 { 693 try 694 { 695 int execWriteStoredProcedureResult = NO_RESULT; 696 697 ArrayList groupMembers = dvdb.getCurrentGroup().getMembers(); 698 699 if (logger.isDebugEnabled()) 700 logger.debug("Broadcasting write store procedure " 701 + proc.getSQLShortForm(dvdb.getSQLShortFormLength()) 702 + (proc.isAutoCommit() ? "" : " transaction " 703 + proc.getTransactionId()) + ") to all controllers (" 704 + dvdb.getChannel().getLocalMembership() + "->" 705 + groupMembers.toString() + ")"); 706 707 MulticastResponse responses; 709 try 710 { 711 responses = dvdb.getMulticastRequestAdapter().multicastMessage( 712 groupMembers, new ExecWriteStoredProcedure(proc), 713 MulticastRequestAdapter.WAIT_ALL, 714 CJDBCGroupMessage.defaultCastTimeOut); } 716 catch (Exception e) 717 { 718 String msg = "An error occured while executing distributed write stored procedure " 719 + proc.getId(); 720 logger.warn(msg, e); 721 throw new SQLException (msg + " (" + e + ")"); 722 } 723 724 if (logger.isDebugEnabled()) 725 logger.debug("Stored procedure " 726 + proc.getSQLShortForm(dvdb.getSQLShortFormLength()) 727 + " completed."); 728 729 if (responses.getFailedMembers() != null) 730 { logger.warn(responses.getFailedMembers().size() 732 + " controller(s) died during execution of stored procedure " 733 + proc.getId()); 734 } 735 736 ArrayList failedOnAllBackends = null; 738 ArrayList controllersWithoutBackends = null; 740 SQLException exception = null; 741 int size = groupMembers.size(); 742 for (int i = 0; i < size; i++) 744 { 745 Member member = (Member) groupMembers.get(i); 746 if ((responses.getFailedMembers() != null) 747 && responses.getFailedMembers().contains(member)) 748 { 749 logger.warn("Controller " + member + " is suspected of failure."); 750 continue; 751 } 752 Object r = responses.getResult(member); 753 if (r instanceof Integer ) 754 { 755 if (execWriteStoredProcedureResult == NO_RESULT) 756 execWriteStoredProcedureResult = ((Integer ) r).intValue(); 757 } 758 else if (r instanceof AllBackendsFailedException) 759 { 760 if (failedOnAllBackends == null) 761 failedOnAllBackends = new ArrayList (); 762 failedOnAllBackends.add(member); 763 } 764 else if (r instanceof NoMoreBackendException) 765 { 766 if (controllersWithoutBackends == null) 767 controllersWithoutBackends = new ArrayList (); 768 controllersWithoutBackends.add(member); 769 if (logger.isDebugEnabled()) 770 logger.debug("Controller " + member 771 + " has no more backends to execute query (" + r + ")"); 772 } 773 else if (r instanceof SQLException ) 774 { 775 String msg = "Stored procedure " + proc.getId() 776 + " failed on controller " + member + " (" + r + ")"; 777 logger.warn(msg); 778 exception = (SQLException ) r; 779 } 780 } 781 782 if (failedOnAllBackends != null) 783 { try 785 { 786 dvdb.getMulticastRequestAdapter().multicastMessage( 787 failedOnAllBackends, 788 new NotifyCompletion(proc, 789 execWriteStoredProcedureResult != NO_RESULT), 790 MulticastRequestAdapter.WAIT_NONE, 791 CJDBCGroupMessage.defaultCastTimeOut); } 794 catch (Exception e) 795 { 796 String msg = "An error occured while notifying all controllers of failure of write stored procedure " 797 + proc.getId(); 798 logger.warn(msg, e); 799 throw new SQLException (msg + " (" + e + ")"); 800 } 801 } 802 803 if (execWriteStoredProcedureResult != NO_RESULT) 804 { 805 if (logger.isDebugEnabled()) 806 logger.debug("Stored procedure " + proc.getId() 807 + " completed successfully."); 808 return execWriteStoredProcedureResult; } 810 811 813 if (controllersWithoutBackends != null) 814 { 817 int nbOfControllers = controllersWithoutBackends.size(); 818 for (int i = 0; i < nbOfControllers; i++) 819 { 820 Member member = (Member) controllersWithoutBackends.get(i); 821 NoMoreBackendException nmbe = (NoMoreBackendException) responses 822 .getResult(member); 823 try 824 { 825 ArrayList dest = new ArrayList (); 826 dest.add(member); 827 dvdb.getMulticastRequestAdapter().multicastMessage(dest, 828 new UnlogRequest(proc, nmbe.getRecoveryLogId()), 829 MulticastRequestAdapter.WAIT_NONE, 830 CJDBCGroupMessage.defaultCastTimeOut); } 833 catch (Exception e) 834 { 835 String msg = "An error occured while notifying controllers " 836 + member 837 + " to unlog failed distributed write stored procedure " 838 + proc.getId(); 839 logger.error(msg, e); 840 } 841 } 842 } 843 844 if (exception != null) 845 throw exception; 846 else 847 { 848 String msg = "Stored procedure '" + proc 849 + "' failed on all controllers"; 850 logger.warn(msg); 851 throw new SQLException (msg); 852 } 853 } 854 catch (SQLException e) 855 { 856 String msg = Translate.get("loadbalancer.request.failed", new String []{ 857 proc.getSQLShortForm(vdb.getSQLShortFormLength()), e.getMessage()}); 858 logger.warn(msg); 859 throw e; 860 } 861 } 862 863 867 public void distributedCommit(String login, long transactionId) 868 throws SQLException 869 { 870 try 871 { 872 ArrayList groupMembers = dvdb.getCurrentGroup().getMembers(); 873 if (logger.isDebugEnabled()) 874 logger.debug("Broadcasting transaction " + transactionId 875 + " commit to all controllers (" 876 + dvdb.getChannel().getLocalMembership() + "->" 877 + groupMembers.toString() + ")"); 878 879 MulticastResponse responses; 881 try 882 { 883 responses = dvdb.getMulticastRequestAdapter().multicastMessage( 884 groupMembers, new Commit(login, transactionId), 885 MulticastRequestAdapter.WAIT_ALL, 886 CJDBCGroupMessage.defaultCastTimeOut); } 888 catch (Exception e) 889 { 890 String msg = "An error occured while executing distributed rollback for transaction " 891 + transactionId; 892 logger.warn(msg, e); 893 throw new SQLException (msg + "(" + e + ")"); 894 } 895 896 if (logger.isDebugEnabled()) 897 logger.debug("Commit of transaction " + transactionId + " completed."); 898 899 if (responses.getFailedMembers() != null) 900 { logger.warn(responses.getFailedMembers().size() 902 + " controller(s) died during execution of commit for transaction " 903 + transactionId); 904 } 905 906 ArrayList failedOnAllBackends = null; 908 ArrayList controllersWithoutBackends = null; 910 SQLException exception = null; 911 int size = groupMembers.size(); 912 boolean success = false; 913 for (int i = 0; i < size; i++) 915 { 916 Member member = (Member) groupMembers.get(i); 917 if ((responses.getFailedMembers() != null) 918 && responses.getFailedMembers().contains(member)) 919 { 920 logger.warn("Controller " + member + " is suspected of failure."); 921 continue; 922 } 923 Object r = responses.getResult(member); 924 if (r instanceof Boolean ) 925 { 926 if (((Boolean ) r).booleanValue()) 927 success = true; 928 else 929 logger.error("Unexpected result for controller " + member); 930 } 931 else if (r instanceof NoMoreBackendException) 932 { 933 if (controllersWithoutBackends == null) 934 controllersWithoutBackends = new ArrayList (); 935 controllersWithoutBackends.add(member); 936 if (logger.isDebugEnabled()) 937 logger.debug("Controller " + member 938 + " has no more backends to commit transaction " 939 + transactionId + " (" + r + ")"); 940 } 941 else if (r instanceof AllBackendsFailedException) 942 { 943 if (failedOnAllBackends == null) 944 failedOnAllBackends = new ArrayList (); 945 failedOnAllBackends.add(member); 946 if (logger.isDebugEnabled()) 947 logger.debug("Commit failed on all backends of controller " 948 + member + " (" + r + ")"); 949 } 950 else if (r instanceof SQLException ) 951 { 952 String msg = "Commit of transaction " + transactionId 953 + " failed on controller " + member + " (" + r + ")"; 954 logger.warn(msg); 955 exception = (SQLException ) r; 956 } 957 } 958 959 if (failedOnAllBackends != null) 960 { AbstractRequest request = new UnknownRequest("commit", false, 0, "\n"); 963 request.setTransactionId(transactionId); 964 try 965 { 966 dvdb.getMulticastRequestAdapter().multicastMessage( 967 failedOnAllBackends, new NotifyCompletion(request, success), 968 MulticastRequestAdapter.WAIT_NONE, 969 CJDBCGroupMessage.defaultCastTimeOut); } 971 catch (Exception e) 972 { 973 String msg = "An error occured while notifying all controllers of failure to commit transaction " 974 + transactionId; 975 logger.warn(msg, e); 976 throw new SQLException (msg + " (" + e + ")"); 977 } 978 } 979 980 if (success) 981 return; 983 985 if (controllersWithoutBackends != null) 986 { 989 int nbOfControllers = controllersWithoutBackends.size(); 990 for (int i = 0; i < nbOfControllers; i++) 991 { 992 Member member = (Member) controllersWithoutBackends.get(i); 993 NoMoreBackendException nmbe = (NoMoreBackendException) responses 994 .getResult(member); 995 try 996 { 997 ArrayList dest = new ArrayList (); 998 dest.add(member); 999 dvdb.getMulticastRequestAdapter().multicastMessage( 1002 dest, 1003 new UnlogCommit(new TransactionMarkerMetaData(transactionId, 1004 nmbe.getRecoveryLogId(), nmbe.getLogin())), 1005 MulticastRequestAdapter.WAIT_NONE, 1006 CJDBCGroupMessage.defaultCastTimeOut); } 1009 catch (Exception e) 1010 { 1011 String msg = "An error occured while notifying controllers " 1012 + member + " to unlog failed commit for transaction " 1013 + transactionId; 1014 logger.error(msg, e); 1015 } 1016 } 1017 } 1018 1019 if (exception != null) 1020 throw exception; 1021 else 1022 { 1023 String msg = "Transaction " + transactionId 1024 + " failed to commit on all controllers"; 1025 logger.warn(msg); 1026 throw new SQLException (msg); 1027 } 1028 } 1029 catch (SQLException e) 1030 { 1031 String msg = "Transaction " + transactionId + " commit failed (" + e 1032 + ")"; 1033 logger.warn(msg); 1034 throw e; 1035 } 1036 } 1037 1038 1042 public void distributedRollback(String login, long transactionId) 1043 throws SQLException 1044 { 1045 try 1046 { 1047 ArrayList groupMembers = dvdb.getCurrentGroup().getMembers(); 1048 if (logger.isDebugEnabled()) 1049 logger.debug("Broadcasting transaction " + transactionId 1050 + " rollback to all controllers (" 1051 + dvdb.getChannel().getLocalMembership() + "->" 1052 + groupMembers.toString() + ")"); 1053 1054 MulticastResponse responses; 1056 try 1057 { 1058 responses = dvdb.getMulticastRequestAdapter().multicastMessage( 1059 groupMembers, new Rollback(login, transactionId), 1060 MulticastRequestAdapter.WAIT_ALL, 1061 CJDBCGroupMessage.defaultCastTimeOut); } 1064 catch (Exception e) 1065 { 1066 String msg = "An error occured while executing distributed rollback for transaction " 1067 + transactionId; 1068 logger.warn(msg, e); 1069 throw new SQLException (msg + "(" + e + ")"); 1070 } 1071 1072 if (logger.isDebugEnabled()) 1073 logger 1074 .debug("rollback of transaction " + transactionId + " completed."); 1075 1076 if (responses.getFailedMembers() != null) 1077 { logger 1079 .warn(responses.getFailedMembers().size() 1080 + " controller(s) died during execution of rollback for transaction " 1081 + transactionId); 1082 } 1083 1084 ArrayList failedOnAllBackends = null; 1086 ArrayList controllersWithoutBackends = null; 1088 SQLException exception = null; 1089 int size = groupMembers.size(); 1090 boolean success = false; 1091 for (int i = 0; i < size; i++) 1093 { 1094 Member member = (Member) groupMembers.get(i); 1095 if ((responses.getFailedMembers() != null) 1096 && responses.getFailedMembers().contains(member)) 1097 { 1098 logger.warn("Controller " + member + " is suspected of failure."); 1099 continue; 1100 } 1101 Object r = responses.getResult(member); 1102 if (r instanceof Boolean ) 1103 { 1104 if (((Boolean ) r).booleanValue()) 1105 success = true; 1106 else 1107 logger.error("Unexpected result for controller " + member); 1108 } 1109 else if (r instanceof NoMoreBackendException) 1110 { 1111 if (controllersWithoutBackends == null) 1112 controllersWithoutBackends = new ArrayList (); 1113 controllersWithoutBackends.add(member); 1114 if (logger.isDebugEnabled()) 1115 logger.debug("Controller " + member 1116 + " has no more backends to rollback transaction " 1117 + transactionId + " (" + r + ")"); 1118 } 1119 else if (r instanceof AllBackendsFailedException) 1120 { 1121 if (failedOnAllBackends == null) 1122 failedOnAllBackends = new ArrayList (); 1123 failedOnAllBackends.add(member); 1124 if (logger.isDebugEnabled()) 1125 logger.debug("rollback failed on all backends of controller " 1126 + member + " (" + r + ")"); 1127 } 1128 else if (r instanceof SQLException ) 1129 { 1130 String msg = "rollback of transaction " + transactionId 1131 + " failed on controller " + member + " (" + r + ")"; 1132 logger.warn(msg); 1133 exception = (SQLException ) r; 1134 } 1135 } 1136 1137 if (failedOnAllBackends != null) 1138 { AbstractRequest request = new UnknownRequest("rollback", false, 0, "\n"); 1141 request.setTransactionId(transactionId); 1142 try 1143 { 1144 dvdb.getMulticastRequestAdapter().multicastMessage( 1145 failedOnAllBackends, new NotifyCompletion(request, success), 1146 MulticastRequestAdapter.WAIT_NONE, 1147 CJDBCGroupMessage.defaultCastTimeOut); } 1149 catch (Exception e) 1150 { 1151 String msg = "An error occured while notifying all controllers of failure to rollback transaction " 1152 + transactionId; 1153 logger.warn(msg, e); 1154 throw new SQLException (msg + " (" + e + ")"); 1155 } 1156 } 1157 1158 if (success) 1159 return; 1161 if (exception != null) 1162 throw exception; 1163 1164 1166 if (controllersWithoutBackends != null) 1167 { 1170 int nbOfControllers = controllersWithoutBackends.size(); 1171 for (int i = 0; i < nbOfControllers; i++) 1172 { 1173 Member member = (Member) controllersWithoutBackends.get(i); 1174 NoMoreBackendException nmbe = (NoMoreBackendException) responses 1175 .getResult(member); 1176 try 1177 { 1178 ArrayList dest = new ArrayList (); 1179 dest.add(member); 1180 dvdb.getMulticastRequestAdapter().multicastMessage( 1183 dest, 1184 new UnlogRollback(new TransactionMarkerMetaData(transactionId, 1185 nmbe.getRecoveryLogId(), nmbe.getLogin())), 1186 MulticastRequestAdapter.WAIT_NONE, 1187 CJDBCGroupMessage.defaultCastTimeOut); } 1190 catch (Exception e) 1191 { 1192 String msg = "An error occured while notifying controllers " 1193 + member + " to unlog failed rollback for transaction " 1194 + transactionId; 1195 logger.error(msg, e); 1196 } 1197 } 1198 } 1199 1200 if (exception != null) 1201 throw exception; 1202 else 1203 { 1204 String msg = "Transaction " + transactionId 1205 + " failed to rollback on all controllers"; 1206 logger.warn(msg); 1207 throw new SQLException (msg); 1208 } 1209 } 1210 catch (SQLException e) 1211 { 1212 String msg = "Transaction " + transactionId + " rollback failed (" + e 1213 + ")"; 1214 logger.warn(msg); 1215 throw e; 1216 } 1217 } 1218 1219 1223 public void distributedRollback(long transactionId, String savepointName) 1224 throws SQLException 1225 { 1226 try 1227 { 1228 ArrayList groupMembers = dvdb.getCurrentGroup().getMembers(); 1229 if (logger.isDebugEnabled()) 1230 logger.debug("Broadcasting rollback to savepoint " + savepointName 1231 + " for transaction " + transactionId + " to all controllers (" 1232 + dvdb.getChannel().getLocalMembership() + "->" 1233 + groupMembers.toString() + ")"); 1234 1235 MulticastResponse responses; 1237 try 1238 { 1239 responses = dvdb.getMulticastRequestAdapter().multicastMessage( 1240 groupMembers, 1241 new RollbackToSavepoint(transactionId, savepointName), 1242 MulticastRequestAdapter.WAIT_ALL, 1243 CJDBCGroupMessage.defaultCastTimeOut); 1244 } 1245 catch (Exception e) 1246 { 1247 String msg = "An error occured while executing distributed rollback to" 1248 + " savepoint " + savepointName + " for transaction " 1249 + transactionId; 1250 logger.warn(msg, e); 1251 throw new SQLException (msg + "(" + e + ")"); 1252 } 1253 1254 if (logger.isDebugEnabled()) 1255 logger.debug("rollback to savepoint " + savepointName + " for " 1256 + "transaction " + transactionId + " completed."); 1257 1258 if (responses.getFailedMembers() != null) 1259 { logger.warn(responses.getFailedMembers().size() + " controller(s) died" 1261 + " during execution of rollback to savepoint " + savepointName 1262 + " for transaction " + transactionId); 1263 } 1264 1265 ArrayList failedOnAllBackends = null; 1267 ArrayList controllersWithoutBackends = null; 1269 SQLException exception = null; 1270 int size = groupMembers.size(); 1271 boolean success = false; 1272 for (int i = 0; i < size; i++) 1274 { 1275 Member member = (Member) groupMembers.get(i); 1276 if ((responses.getFailedMembers() != null) 1277 && responses.getFailedMembers().contains(member)) 1278 { 1279 logger.warn("Controller " + member + " is suspected of failure."); 1280 continue; 1281 } 1282 Object r = responses.getResult(member); 1283 if (r instanceof Boolean ) 1284 { 1285 if (((Boolean ) r).booleanValue()) 1286 success = true; 1287 else 1288 logger.error("Unexpected result for controller " + member); 1289 } 1290 else if (r instanceof NoMoreBackendException) 1291 { 1292 if (controllersWithoutBackends == null) 1293 controllersWithoutBackends = new ArrayList (); 1294 controllersWithoutBackends.add(member); 1295 if (logger.isDebugEnabled()) 1296 logger.debug("Controller " + member + " has no more backends to " 1297 + "rollback to savepoint " + savepointName + " for " 1298 + "transaction " + transactionId + " (" + r + ")"); 1299 } 1300 else if (r instanceof AllBackendsFailedException) 1301 { 1302 if (failedOnAllBackends == null) 1303 failedOnAllBackends = new ArrayList (); 1304 failedOnAllBackends.add(member); 1305 if (logger.isDebugEnabled()) 1306 logger.debug("rollback to savepoint failed on all backends of " 1307 + "controller " + member + " (" + r + ")"); 1308 } 1309 else if (r instanceof SQLException ) 1310 { 1311 String msg = "rollback to savepoint " + savepointName + " for " 1312 + "transaction " + transactionId + " failed on controller " 1313 + member + " (" + r + ")"; 1314 logger.warn(msg); 1315 exception = (SQLException ) r; 1316 } 1317 } 1318 1319 if (failedOnAllBackends != null) 1320 { AbstractRequest request = new UnknownRequest("rollback " 1323 + savepointName, false, 0, "\n"); 1324 request.setTransactionId(transactionId); 1325 try 1326 { 1327 dvdb.getMulticastRequestAdapter().multicastMessage( 1328 failedOnAllBackends, new NotifyCompletion(request, success), 1329 MulticastRequestAdapter.WAIT_NONE, 1330 CJDBCGroupMessage.defaultCastTimeOut); 1331 } 1332 catch (Exception e) 1333 { 1334 String msg = "An error occured while notifying all controllers of " 1335 + "failure to rollback to savepoint " + savepointName + " for " 1336 + "transaction " + transactionId; 1337 logger.warn(msg, e); 1338 throw new SQLException (msg + " (" + e + ")"); 1339 } 1340 } 1341 1342 if (success) 1343 return; 1345 if (exception != null) 1346 throw exception; 1347 1348 1350 if (controllersWithoutBackends != null) 1351 { int nbOfControllers = controllersWithoutBackends.size(); 1354 for (int i = 0; i < nbOfControllers; i++) 1355 { 1356 Member member = (Member) controllersWithoutBackends.get(i); 1357 NoMoreBackendException nmbe = (NoMoreBackendException) responses 1358 .getResult(member); 1359 try 1360 { 1361 ArrayList dest = new ArrayList (); 1362 dest.add(member); 1363 dvdb.getMulticastRequestAdapter().multicastMessage( 1366 dest, 1367 new UnlogRollback(new TransactionMarkerMetaData(transactionId, 1368 nmbe.getRecoveryLogId(), nmbe.getLogin())), 1369 MulticastRequestAdapter.WAIT_NONE, 1370 CJDBCGroupMessage.defaultCastTimeOut); 1371 } 1372 catch (Exception e) 1373 { 1374 String msg = "An error occured while notifying controllers " 1375 + member + " to unlog failed rollback to savepoint " 1376 + savepointName + " for transaction " + transactionId; 1377 logger.error(msg, e); 1378 } 1379 } 1380 } 1381 1382 if (exception != null) 1383 throw exception; 1384 else 1385 { 1386 String msg = "Rollback to savepoint " + savepointName + " for " 1387 + "transaction " + transactionId + " failed on all controllers"; 1388 logger.warn(msg); 1389 throw new SQLException (msg); 1390 } 1391 } 1392 catch (SQLException e) 1393 { 1394 String msg = "Rollback to savepoint " + savepointName + " for " 1395 + "transaction " + transactionId + " failed (" + e + ")"; 1396 logger.warn(msg); 1397 throw e; 1398 } 1399 } 1400 1401 1405 public void distributedSetSavepoint(long transactionId, String name) 1406 throws SQLException 1407 { 1408 try 1409 { 1410 ArrayList groupMembers = dvdb.getCurrentGroup().getMembers(); 1411 if (logger.isDebugEnabled()) 1412 logger.debug("Broadcasting set savepoint " + name + " to transaction " 1413 + transactionId + " to all controllers (" 1414 + dvdb.getChannel().getLocalMembership() + "->" 1415 + groupMembers.toString() + ")"); 1416 1417 MulticastResponse responses; 1419 try 1420 { 1421 responses = dvdb.getMulticastRequestAdapter().multicastMessage( 1422 groupMembers, new SetSavepoint(transactionId, name), 1423 MulticastRequestAdapter.WAIT_ALL, 1424 CJDBCGroupMessage.defaultCastTimeOut); 1425 } 1426 catch (Exception e) 1427 { 1428 String msg = "An error occured while executing distributed set " 1429 + "savepoint " + name + " to transaction " + transactionId; 1430 logger.warn(msg, e); 1431 throw new SQLException (msg + "(" + e + ")"); 1432 } 1433 1434 if (logger.isDebugEnabled()) 1435 logger.debug("set savepoint " + name + " to transaction " 1436 + transactionId + " completed."); 1437 1438 if (responses.getFailedMembers() != null) 1439 { logger.warn(responses.getFailedMembers().size() + " controller(s) died" 1441 + " during execution of set savepoint " + name + " to transaction " 1442 + transactionId); 1443 } 1444 1445 ArrayList failedOnAllBackends = null; 1447 ArrayList controllersWithoutBackends = null; 1449 SQLException exception = null; 1450 int size = groupMembers.size(); 1451 boolean success = false; 1452 for (int i = 0; i < size; i++) 1454 { 1455 Member member = (Member) groupMembers.get(i); 1456 if ((responses.getFailedMembers() != null) 1457 && responses.getFailedMembers().contains(member)) 1458 { 1459 logger.warn("Controller " + member + " is suspected of failure."); 1460 continue; 1461 } 1462 Object r = responses.getResult(member); 1463 if (r instanceof Boolean ) 1464 { 1465 if (((Boolean ) r).booleanValue()) 1466 success = true; 1467 else 1468 logger.error("Unexpected result for controller " + member); 1469 } 1470 else if (r instanceof NoMoreBackendException) 1471 { 1472 if (controllersWithoutBackends == null) 1473 controllersWithoutBackends = new ArrayList (); 1474 controllersWithoutBackends.add(member); 1475 if (logger.isDebugEnabled()) 1476 logger.debug("Controller " + member + " has no more backends to " 1477 + "set savepoint " + name + " to transaction " + transactionId 1478 + " (" + r + ")"); 1479 } 1480 else if (r instanceof AllBackendsFailedException) 1481 { 1482 if (failedOnAllBackends == null) 1483 failedOnAllBackends = new ArrayList (); 1484 failedOnAllBackends.add(member); 1485 if (logger.isDebugEnabled()) 1486 logger.debug("set savepoint failed on all backends of controller " 1487 + member + " (" + r + ")"); 1488 } 1489 else if (r instanceof SQLException ) 1490 { 1491 String msg = "set savepoint " + name + " to transaction " 1492 + transactionId + " failed on controller " + member + " (" + r 1493 + ")"; 1494 logger.warn(msg); 1495 exception = (SQLException ) r; 1496 } 1497 } 1498 1499 if (failedOnAllBackends != null) 1500 { AbstractRequest request = new UnknownRequest("savepoint " + name, 1503 false, 0, "\n"); 1504 request.setTransactionId(transactionId); 1505 try 1506 { 1507 dvdb.getMulticastRequestAdapter().multicastMessage( 1508 failedOnAllBackends, new NotifyCompletion(request, success), 1509 MulticastRequestAdapter.WAIT_NONE, 1510 CJDBCGroupMessage.defaultCastTimeOut); 1511 } 1512 catch (Exception e) 1513 { 1514 String msg = "An error occured while notifying all controllers of " 1515 + "failure to set savepoint " + name + " to transaction " 1516 + transactionId; 1517 logger.warn(msg, e); 1518 throw new SQLException (msg + " (" + e + ")"); 1519 } 1520 } 1521 1522 if (success) 1523 return; 1525 if (exception != null) 1526 throw exception; 1527 1528 1530 if (controllersWithoutBackends != null) 1531 { int nbOfControllers = controllersWithoutBackends.size(); 1534 for (int i = 0; i < nbOfControllers; i++) 1535 { 1536 Member member = (Member) controllersWithoutBackends.get(i); 1537 NoMoreBackendException nmbe = (NoMoreBackendException) responses 1538 .getResult(member); 1539 try 1540 { 1541 ArrayList dest = new ArrayList (); 1542 dest.add(member); 1543 dvdb.getMulticastRequestAdapter().multicastMessage( 1546 dest, 1547 new UnlogRollback(new TransactionMarkerMetaData(transactionId, 1548 nmbe.getRecoveryLogId(), nmbe.getLogin())), 1549 MulticastRequestAdapter.WAIT_NONE, 1550 CJDBCGroupMessage.defaultCastTimeOut); 1551 } 1552 catch (Exception e) 1553 { 1554 String msg = "An error occured while notifying controllers " 1555 + member + " to unlog failed set savepoint " + name + " to " 1556 + "transaction " + transactionId; 1557 logger.error(msg, e); 1558 } 1559 } 1560 } 1561 1562 if (exception != null) 1563 throw exception; 1564 else 1565 { 1566 String msg = "Set savepoint " + name + " to transaction " 1567 + transactionId + " failed on all controllers"; 1568 logger.warn(msg); 1569 throw new SQLException (msg); 1570 } 1571 } 1572 catch (SQLException e) 1573 { 1574 String msg = "Set savepoint " + name + " to transaction " + transactionId 1575 + " failed (" + e + ")"; 1576 logger.warn(msg); 1577 throw e; 1578 } 1579 } 1580 1581 1585 public void distributedReleaseSavepoint(long transactionId, String name) 1586 throws SQLException 1587 { 1588 try 1589 { 1590 ArrayList groupMembers = dvdb.getCurrentGroup().getMembers(); 1591 if (logger.isDebugEnabled()) 1592 logger.debug("Broadcasting release savepoint " + name + " from " 1593 + "transaction " + transactionId + " to all controllers (" 1594 + dvdb.getChannel().getLocalMembership() + "->" 1595 + groupMembers.toString() + ")"); 1596 1597 MulticastResponse responses; 1599 try 1600 { 1601 responses = dvdb.getMulticastRequestAdapter().multicastMessage( 1602 groupMembers, new ReleaseSavepoint(transactionId, name), 1603 MulticastRequestAdapter.WAIT_ALL, 1604 CJDBCGroupMessage.defaultCastTimeOut); 1605 } 1606 catch (Exception e) 1607 { 1608 String msg = "An error occured while executing distributed release " 1609 + "savepoint " + name + " from transaction " + transactionId; 1610 logger.warn(msg, e); 1611 throw new SQLException (msg + "(" + e + ")"); 1612 } 1613 1614 if (logger.isDebugEnabled()) 1615 logger.debug("release savepoint " + name + " from transaction " 1616 + transactionId + " completed."); 1617 1618 if (responses.getFailedMembers() != null) 1619 { logger.warn(responses.getFailedMembers().size() + " controller(s) died" 1621 + " during execution of release savepoint " + name + " from " 1622 + "transaction " + transactionId); 1623 } 1624 1625 ArrayList failedOnAllBackends = null; 1627 ArrayList controllersWithoutBackends = null; 1629 SQLException exception = null; 1630 int size = groupMembers.size(); 1631 boolean success = false; 1632 for (int i = 0; i < size; i++) 1634 { 1635 Member member = (Member) groupMembers.get(i); 1636 if ((responses.getFailedMembers() != null) 1637 && responses.getFailedMembers().contains(member)) 1638 { 1639 logger.warn("Controller " + member + " is suspected of failure."); 1640 continue; 1641 } 1642 Object r = responses.getResult(member); 1643 if (r instanceof Boolean ) 1644 { 1645 if (((Boolean ) r).booleanValue()) 1646 success = true; 1647 else 1648 logger.error("Unexpected result for controller " + member); 1649 } 1650 else if (r instanceof NoMoreBackendException) 1651 { 1652 if (controllersWithoutBackends == null) 1653 controllersWithoutBackends = new ArrayList (); 1654 controllersWithoutBackends.add(member); 1655 if (logger.isDebugEnabled()) 1656 logger.debug("Controller " + member + " has no more backends to " 1657 + "release savepoint " + name + " from transaction " 1658 + transactionId + " (" + r + ")"); 1659 } 1660 else if (r instanceof AllBackendsFailedException) 1661 { 1662 if (failedOnAllBackends == null) 1663 failedOnAllBackends = new ArrayList (); 1664 failedOnAllBackends.add(member); 1665 if (logger.isDebugEnabled()) 1666 logger.debug("release savepoint failed on all backends of " 1667 + "controller " + member + " (" + r + ")"); 1668 } 1669 else if (r instanceof SQLException ) 1670 { 1671 String msg = "release savepoint " + name + " from transaction " 1672 + transactionId + " failed on controller " + member + " (" + r 1673 + ")"; 1674 logger.warn(msg); 1675 exception = (SQLException ) r; 1676 } 1677 } 1678 1679 if (failedOnAllBackends != null) 1680 { AbstractRequest request = new UnknownRequest("release " + name, false, 1683 0, "\n"); 1684 request.setTransactionId(transactionId); 1685 try 1686 { 1687 dvdb.getMulticastRequestAdapter().multicastMessage( 1688 failedOnAllBackends, new NotifyCompletion(request, success), 1689 MulticastRequestAdapter.WAIT_NONE, 1690 CJDBCGroupMessage.defaultCastTimeOut); 1691 } 1692 catch (Exception e) 1693 { 1694 String msg = "An error occured while notifying all controllers of " 1695 + "failure to release savepoint " + name + " from transaction " 1696 + transactionId; 1697 logger.warn(msg, e); 1698 throw new SQLException (msg + " (" + e + ")"); 1699 } 1700 } 1701 1702 if (success) 1703 return; 1705 if (exception != null) 1706 throw exception; 1707 1708 1710 if (controllersWithoutBackends != null) 1711 { int nbOfControllers = controllersWithoutBackends.size(); 1714 for (int i = 0; i < nbOfControllers; i++) 1715 { 1716 Member member = (Member) controllersWithoutBackends.get(i); 1717 NoMoreBackendException nmbe = (NoMoreBackendException) responses 1718 .getResult(member); 1719 try 1720 { 1721 ArrayList dest = new ArrayList (); 1722 dest.add(member); 1723 dvdb.getMulticastRequestAdapter().multicastMessage( 1726 dest, 1727 new UnlogRollback(new TransactionMarkerMetaData(transactionId, 1728 nmbe.getRecoveryLogId(), nmbe.getLogin())), 1729 MulticastRequestAdapter.WAIT_NONE, 1730 CJDBCGroupMessage.defaultCastTimeOut); 1731 } 1732 catch (Exception e) 1733 { 1734 String msg = "An error occured while notifying controllers " 1735 + member + " to unlog failed release savepoint " + name 1736 + " from transaction " + transactionId; 1737 logger.error(msg, e); 1738 } 1739 } 1740 } 1741 1742 if (exception != null) 1743 throw exception; 1744 else 1745 { 1746 String msg = "Release savepoint " + name + " from transaction " 1747 + transactionId + " failed on all controllers"; 1748 logger.warn(msg); 1749 throw new SQLException (msg); 1750 } 1751 } 1752 catch (SQLException e) 1753 { 1754 String msg = "Release savepoint " + name + " from transaction " 1755 + transactionId + " failed (" + e + ")"; 1756 logger.warn(msg); 1757 throw e; 1758 } 1759 } 1760} | Popular Tags |