001/* 002 * HA-JDBC: High-Availability JDBC 003 * Copyright (C) 2012 Paul Ferraro 004 * 005 * This program is free software: you can redistribute it and/or modify 006 * it under the terms of the GNU Lesser General Public License as published by 007 * the Free Software Foundation, either version 3 of the License, or 008 * (at your option) any later version. 009 * 010 * This program is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 013 * GNU Lesser General Public License for more details. 014 * 015 * You should have received a copy of the GNU Lesser General Public License 016 * along with this program. If not, see <http://www.gnu.org/licenses/>. 017 */ 018package net.sf.hajdbc.durability.coarse; 019 020import java.util.Map; 021import java.util.SortedMap; 022 023import net.sf.hajdbc.Database; 024import net.sf.hajdbc.DatabaseCluster; 025import net.sf.hajdbc.durability.DurabilityListener; 026import net.sf.hajdbc.durability.InvocationEvent; 027import net.sf.hajdbc.durability.InvocationEventImpl; 028import net.sf.hajdbc.durability.InvokerEvent; 029import net.sf.hajdbc.durability.none.NoDurability; 030import net.sf.hajdbc.invocation.InvocationStrategy; 031import net.sf.hajdbc.invocation.Invoker; 032import net.sf.hajdbc.sql.ProxyFactory; 033import net.sf.hajdbc.state.StateManager; 034 035/** 036 * {@link net.sf.hajdbc.durability.Durability} implementation that tracks invocations only, but not per-database invokers. 037 * This durability level can detect, but not recover from, mid-commit crashes. 038 * @author Paul Ferraro 039 */ 040/** 041 * @author Paul Ferraro 042 * @param <Z> 043 * @param <D> 044 */ 045public class CoarseDurability<Z, D extends Database<Z>> extends NoDurability<Z, D> 046{ 047 protected final DatabaseCluster<Z, D> cluster; 048 049 public CoarseDurability(DatabaseCluster<Z, D> cluster) 050 { 051 this.cluster = cluster; 052 } 053 054 /** 055 * {@inheritDoc} 056 * @see net.sf.hajdbc.durability.none.NoDurability#getInvocationStrategy(net.sf.hajdbc.invocation.InvocationStrategy, net.sf.hajdbc.durability.Durability.Phase, java.lang.Object) 057 */ 058 @Override 059 public InvocationStrategy getInvocationStrategy(final InvocationStrategy strategy, final Phase phase, final Object transactionId) 060 { 061 final DurabilityListener listener = this.cluster.getStateManager(); 062 063 return new InvocationStrategy() 064 { 065 @Override 066 public <ZZ, DD extends Database<ZZ>, T, R, EE extends Exception> SortedMap<DD, R> invoke(ProxyFactory<ZZ, DD, T, EE> proxy, Invoker<ZZ, DD, T, R, EE> invoker) throws EE 067 { 068 InvocationEvent event = new InvocationEventImpl(transactionId, phase, proxy.getExceptionFactory().getType()); 069 070 listener.beforeInvocation(event); 071 072 try 073 { 074 return strategy.invoke(proxy, invoker); 075 } 076 catch (Exception e) 077 { 078 throw proxy.getExceptionFactory().createException(e); 079 } 080 finally 081 { 082 listener.afterInvocation(event); 083 } 084 } 085 }; 086 } 087 088 /** 089 * {@inheritDoc} 090 * @see net.sf.hajdbc.durability.none.NoDurability#recover(java.util.Map) 091 */ 092 @Override 093 public void recover(Map<InvocationEvent, Map<String, InvokerEvent>> invokers) 094 { 095 StateManager stateManager = this.cluster.getStateManager(); 096 097 for (D database: this.cluster.getBalancer().backups()) 098 { 099 this.cluster.deactivate(database, stateManager); 100 } 101 102 for (InvocationEvent event: invokers.keySet()) 103 { 104 stateManager.afterInvocation(event); 105 } 106 } 107}