Skip to content

Commit 2cc0c75

Browse files
committed
CarMart with listeners and transactions
1 parent f8fd2e3 commit 2cc0c75

File tree

4 files changed

+161
-65
lines changed

4 files changed

+161
-65
lines changed

lesson05-infinispan/src/main/java/com/jboss/datagrid/carmart/jsf/PopulateCache.java

+49-19
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
import javax.faces.event.SystemEventListener;
3131
import javax.naming.InitialContext;
3232
import javax.naming.NamingException;
33+
import javax.transaction.UserTransaction;
34+
3335
import org.infinispan.api.BasicCache;
3436
import com.jboss.datagrid.carmart.model.Car;
3537
import com.jboss.datagrid.carmart.model.Car.CarType;
@@ -52,6 +54,8 @@ public class PopulateCache implements SystemEventListener {
5254
private Logger log = Logger.getLogger(this.getClass().getName());
5355

5456
private CacheContainerProvider provider;
57+
58+
private UserTransaction utx;
5559

5660
@Override
5761
public void processEvent(SystemEvent event) throws AbortProcessingException {
@@ -62,25 +66,39 @@ public void processEvent(SystemEvent event) throws AbortProcessingException {
6266
public void startup() {
6367
BasicCache<String, Object> cars = provider.getCacheContainer().getCache(CarManager.CACHE_NAME);
6468
List<String> carNumbers = new ArrayList<String>();
65-
66-
Car c = new Car("Ford Focus", 1.6, CarType.COMBI, "white", "FML 23-25", Country.CZECH_REPUBLIC);
67-
carNumbers.add(c.getNumberPlate());
68-
cars.put(CarManager.encode(c.getNumberPlate()), c);
69-
c = new Car("BMW X3", 2.0, CarType.SEDAN, "gray", "1P3 2632", Country.CZECH_REPUBLIC);
70-
carNumbers.add(c.getNumberPlate());
71-
cars.put(CarManager.encode(c.getNumberPlate()), c);
72-
c = new Car("Ford Mondeo", 2.2, CarType.COMBI, "blue", "1B2 1111", Country.USA);
73-
carNumbers.add(c.getNumberPlate());
74-
cars.put(CarManager.encode(c.getNumberPlate()), c);
75-
c = new Car("Mazda MX-5", 1.8, CarType.CABRIO, "red", "6T4 2526", Country.USA);
76-
carNumbers.add(c.getNumberPlate());
77-
cars.put(CarManager.encode(c.getNumberPlate()), c);
78-
c = new Car("VW Golf", 1.6, CarType.HATCHBACK, "yellow", "2B2 4946", Country.GERMANY);
79-
carNumbers.add(c.getNumberPlate());
80-
cars.put(CarManager.encode(c.getNumberPlate()), c);
81-
// insert a list of cars' number plates
82-
cars.put(CarManager.CAR_NUMBERS_KEY, carNumbers);
83-
log.info("Successfully imported data!");
69+
70+
utx = getUserTransactionFromJNDI();
71+
72+
try {
73+
utx.begin();
74+
Car c = new Car("Ford Focus", 1.6, CarType.COMBI, "white", "FML 23-25", Country.CZECH_REPUBLIC);
75+
carNumbers.add(c.getNumberPlate());
76+
cars.put(CarManager.encode(c.getNumberPlate()), c);
77+
c = new Car("BMW X3", 2.0, CarType.SEDAN, "gray", "1P3 2632", Country.CZECH_REPUBLIC);
78+
carNumbers.add(c.getNumberPlate());
79+
cars.put(CarManager.encode(c.getNumberPlate()), c);
80+
c = new Car("Ford Mondeo", 2.2, CarType.COMBI, "blue", "1B2 1111", Country.USA);
81+
carNumbers.add(c.getNumberPlate());
82+
cars.put(CarManager.encode(c.getNumberPlate()), c);
83+
c = new Car("Mazda MX-5", 1.8, CarType.CABRIO, "red", "6T4 2526", Country.USA);
84+
carNumbers.add(c.getNumberPlate());
85+
cars.put(CarManager.encode(c.getNumberPlate()), c);
86+
c = new Car("VW Golf", 1.6, CarType.HATCHBACK, "yellow", "2B2 4946", Country.GERMANY);
87+
carNumbers.add(c.getNumberPlate());
88+
cars.put(CarManager.encode(c.getNumberPlate()), c);
89+
// insert a list of cars' number plates
90+
cars.put(CarManager.CAR_NUMBERS_KEY, carNumbers);
91+
utx.commit();
92+
log.info("Successfully imported data!");
93+
} catch (Exception e) {
94+
log.warning("An exception occured while populating the database! Rolling back the transaction.");
95+
if (utx != null) {
96+
try {
97+
utx.rollback();
98+
} catch (Exception e1) {
99+
}
100+
}
101+
}
84102
}
85103

86104
private BeanManager getBeanManagerFromJNDI() {
@@ -94,6 +112,18 @@ private BeanManager getBeanManagerFromJNDI() {
94112
}
95113
return (BeanManager) result;
96114
}
115+
116+
private UserTransaction getUserTransactionFromJNDI() {
117+
InitialContext context;
118+
Object result;
119+
try {
120+
context = new InitialContext();
121+
result = context.lookup("java:comp/UserTransaction"); // lookup in JBossAS
122+
} catch (NamingException ex) {
123+
throw new RuntimeException("UserTransaction could not be found in JNDI", ex);
124+
}
125+
return (UserTransaction) result;
126+
}
97127

98128
@SuppressWarnings("unchecked")
99129
public <T> T getContextualInstance(final BeanManager manager, final Class<T> type) {

lesson05-infinispan/src/main/java/com/jboss/datagrid/carmart/session/CarManager.java

+59-26
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ public class CarManager {
4949
private CacheContainerProvider provider;
5050

5151
private BasicCache<String, Object> carCache;
52+
53+
@Inject
54+
private UserTransaction utx;
5255

5356
private String carId;
5457
private Car car = new Car();
@@ -58,27 +61,24 @@ public CarManager() {
5861

5962
public String addNewCar() {
6063
carCache = provider.getCacheContainer().getCache(CACHE_NAME);
61-
List<String> carNumbers = getNumberPlateList(carCache);
62-
carNumbers.add(car.getNumberPlate());
63-
carCache.put(CAR_NUMBERS_KEY, carNumbers);
64-
carCache.put(CarManager.encode(car.getNumberPlate()), car);
65-
return "home";
66-
}
67-
68-
public String addNewCarWithRollback() {
69-
boolean throwInducedException = true;
70-
carCache = provider.getCacheContainer().getCache(CACHE_NAME);
71-
List<String> carNumbers = getNumberPlateList(carCache);
72-
carNumbers.add(car.getNumberPlate());
73-
// store the new list of car numbers and then throw an exception -> roll-back
74-
// the car number list should not be stored in the cache
75-
carCache.put(CAR_NUMBERS_KEY, carNumbers);
76-
if (throwInducedException)
77-
throw new RuntimeException("Induced exception");
78-
carCache.put(CarManager.encode(car.getNumberPlate()), car);
64+
try {
65+
utx.begin();
66+
List<String> carNumbers = getNumberPlateList(carCache);
67+
carNumbers.add(car.getNumberPlate());
68+
carCache.put(CAR_NUMBERS_KEY, carNumbers);
69+
carCache.put(CarManager.encode(car.getNumberPlate()), car);
70+
utx.commit();
71+
} catch (Exception e) {
72+
if (utx != null) {
73+
try {
74+
utx.rollback();
75+
} catch (Exception e1) {
76+
}
77+
}
78+
}
7979
return "home";
8080
}
81-
81+
8282
/**
8383
* Operate on a clone of car number list
8484
*/
@@ -96,25 +96,58 @@ private List<String> getNumberPlateList(BasicCache<String, Object> carCacheLoc)
9696

9797
public String showCarDetails(String numberPlate) {
9898
carCache = provider.getCacheContainer().getCache(CACHE_NAME);
99-
this.car = (Car) carCache.get(encode(numberPlate));
99+
try {
100+
utx.begin();
101+
this.car = (Car) carCache.get(encode(numberPlate));
102+
utx.commit();
103+
} catch (Exception e) {
104+
if (utx != null) {
105+
try {
106+
utx.rollback();
107+
} catch (Exception e1) {
108+
}
109+
}
110+
}
100111
return "showdetails";
101112
}
102113

103114
public List<String> getCarList() {
104115
List<String> result = null;
105116
// retrieve a cache
106117
carCache = provider.getCacheContainer().getCache(CACHE_NAME);
107-
// retrieve a list of number plates from the cache
108-
result = getNumberPlateList(carCache);
118+
try {
119+
utx.begin();
120+
// retrieve a list of number plates from the cache
121+
result = getNumberPlateList(carCache);
122+
utx.commit();
123+
} catch (Exception e) {
124+
if (utx != null) {
125+
try {
126+
utx.rollback();
127+
} catch (Exception e1) {
128+
}
129+
}
130+
}
109131
return result;
110132
}
111133

112134
public String removeCar(String numberPlate) {
113135
carCache = provider.getCacheContainer().getCache(CACHE_NAME);
114-
carCache.remove(encode(numberPlate));
115-
List<String> carNumbers = getNumberPlateList(carCache);
116-
carNumbers.remove(numberPlate);
117-
carCache.put(CAR_NUMBERS_KEY, carNumbers);
136+
try {
137+
utx.begin();
138+
carCache.remove(encode(numberPlate));
139+
List<String> carNumbers = getNumberPlateList(carCache);
140+
carNumbers.remove(numberPlate);
141+
carCache.put(CAR_NUMBERS_KEY, carNumbers);
142+
utx.commit();
143+
} catch (Exception e) {
144+
if (utx != null) {
145+
try {
146+
utx.rollback();
147+
} catch (Exception e1) {
148+
}
149+
}
150+
}
118151
return null;
119152
}
120153

lesson05-infinispan/src/main/java/com/jboss/datagrid/carmart/session/JBossASCacheContainerProvider.java

+21-11
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,18 @@
2525
import javax.annotation.PreDestroy;
2626
import javax.enterprise.context.ApplicationScoped;
2727
import org.infinispan.api.BasicCacheContainer;
28+
import org.infinispan.configuration.cache.CacheMode;
2829
import org.infinispan.configuration.cache.Configuration;
2930
import org.infinispan.configuration.cache.ConfigurationBuilder;
3031
import org.infinispan.configuration.global.GlobalConfiguration;
3132
import org.infinispan.configuration.global.GlobalConfigurationBuilder;
33+
import org.infinispan.eviction.EvictionStrategy;
3234
import org.infinispan.manager.DefaultCacheManager;
35+
import org.infinispan.transaction.LockingMode;
36+
import org.infinispan.transaction.TransactionMode;
37+
import org.infinispan.transaction.lookup.GenericTransactionManagerLookup;
38+
import org.infinispan.util.concurrent.IsolationLevel;
39+
3340
import com.jboss.datagrid.carmart.session.CacheContainerProvider;
3441

3542
/**
@@ -48,17 +55,20 @@ public class JBossASCacheContainerProvider implements CacheContainerProvider {
4855

4956
public BasicCacheContainer getCacheContainer() {
5057
if (manager == null) {
51-
52-
53-
//*************** amend the configuration ***************
54-
55-
GlobalConfiguration glob = new GlobalConfigurationBuilder().build();
56-
Configuration loc = new ConfigurationBuilder().build();
57-
58-
//*************** amend the configuration ***************
59-
60-
61-
manager = new DefaultCacheManager(glob, loc, true); //true means start the cache manager immediately
58+
GlobalConfiguration glob = new GlobalConfigurationBuilder()
59+
.nonClusteredDefault().globalJmxStatistics().enable()
60+
.jmxDomain("org.infinispan.lesson05") //prevent collision with non-transactional carmart
61+
.build();
62+
Configuration loc = new ConfigurationBuilder()
63+
.jmxStatistics().enable()
64+
.clustering().cacheMode(CacheMode.LOCAL)
65+
.transaction().transactionMode(TransactionMode.TRANSACTIONAL).autoCommit(false)
66+
.lockingMode(LockingMode.OPTIMISTIC).transactionManagerLookup(new GenericTransactionManagerLookup())
67+
.locking().isolationLevel(IsolationLevel.REPEATABLE_READ)
68+
.eviction().maxEntries(4).strategy(EvictionStrategy.LRU)
69+
.loaders().passivation(true).addFileCacheStore().purgeOnStartup(true)
70+
.build();
71+
manager = new DefaultCacheManager(glob, loc, true);
6272
log.info("=== Using DefaultCacheManager (library mode) ===");
6373
}
6474
return manager;

lesson05-infinispan/src/main/java/com/jboss/datagrid/carmart/session/LocalStatisticsProvider.java

+32-9
Original file line numberDiff line numberDiff line change
@@ -22,37 +22,60 @@
2222
package com.jboss.datagrid.carmart.session;
2323

2424
import javax.annotation.PostConstruct;
25-
import javax.enterprise.context.RequestScoped;
25+
import javax.enterprise.context.ApplicationScoped;
2626
import javax.inject.Inject;
2727
import javax.inject.Named;
2828
import org.infinispan.manager.DefaultCacheManager;
29-
import org.infinispan.stats.Stats;
29+
import org.infinispan.notifications.Listener;
30+
import org.infinispan.notifications.cachelistener.annotation.CacheEntryCreated;
31+
import org.infinispan.notifications.cachelistener.annotation.CacheEntryRemoved;
32+
import org.infinispan.notifications.cachelistener.annotation.CacheEntryVisited;
33+
import org.infinispan.notifications.cachelistener.event.CacheEntryCreatedEvent;
34+
import org.infinispan.notifications.cachelistener.event.CacheEntryRemovedEvent;
35+
import org.infinispan.notifications.cachelistener.event.CacheEntryVisitedEvent;
3036
import com.jboss.datagrid.carmart.session.StatisticsProvider;
3137

3238
@Named("stats")
33-
@RequestScoped
39+
@ApplicationScoped //use application scope so that we can get overall statistics
40+
@Listener
3441
public class LocalStatisticsProvider implements StatisticsProvider {
3542

3643
@Inject
3744
private CacheContainerProvider provider;
3845

39-
private Stats stats;
46+
int visits;
47+
int creations;
48+
int removals;
4049

4150
@PostConstruct
4251
public void getStatsObject() {
43-
stats = ((DefaultCacheManager) provider.getCacheContainer()).getCache(CarManager.CACHE_NAME).getAdvancedCache()
44-
.getStats();
52+
((DefaultCacheManager) provider.getCacheContainer()).getCache(CarManager.CACHE_NAME).addListener(this);
53+
}
54+
55+
@CacheEntryCreated
56+
public void print(CacheEntryCreatedEvent event) {
57+
creations++;
58+
}
59+
60+
@CacheEntryVisited
61+
public void print(CacheEntryVisitedEvent event) {
62+
visits++;
63+
}
64+
65+
@CacheEntryRemoved
66+
public void print(CacheEntryRemovedEvent event) {
67+
removals++;
4568
}
4669

4770
public String getVisits() {
48-
return String.valueOf(stats.getHits());
71+
return String.valueOf(visits);
4972
}
5073

5174
public String getCreations() {
52-
return String.valueOf(stats.getStores());
75+
return String.valueOf(creations);
5376
}
5477

5578
public String getRemovals() {
56-
return String.valueOf(stats.getRemoveHits());
79+
return String.valueOf(removals);
5780
}
5881
}

0 commit comments

Comments
 (0)