Akka && Java && Collections && Transactions
集合事务 public class Scores { final private TransactionalMap<String, Integer> scoreValues = new TransactionalMap<String, Integer>(); final private Ref<Long> updates = new Ref<Long>(0L); public void updateScore(final String name, final int score) { new Atomic() { public Object atomically() { scoreValues.put(name, score); updates.swap(updates.get() + 1); if (score == 13) throw new RuntimeException("Reject this score"); return null; } }.execute(); } public Iterable<String> getNames() { return asJavaIterable(scoreValues.keySet()); } public long getNumberOfUpdates() { return updates.get(); } public int getScore(final String name) { return scoreValues.get(name).get(); } } /** * In the updateScore() method, we set the score value for a player and increment the update count in a transaction. Both the fields scoreValue of type TransactionalMap and updates of type Ref are managed. The TransactionalMap supports methods we’d expect on a Map, but these methods are transactional—any changes we make to them are discarded if the transaction is rolled back. To see this effect in action, we roll back the transaction after making the change if the score value is 13.//13 异常回滚 In Java we can use the for-each statement, like for(String name : collectionOfNames), if the collection implements the Iterable interface. The TransactionalMap is a Scala collection and does not directly support that interface. No worries—Scala provides a façade called JavaConversions that provides convenience methods to get favorable Java interfaces. We’re using its asJavaIterable() method to get the interface we desire in the getNames() method. */ //test public class UseScores { public static void main(final String[] args) { final Scores scores = new Scores(); scores.updateScore("Joe", 14); scores.updateScore("Sally", 15); scores.updateScore("Bernie", 12); System.out.println("Number of updates: " + scores.getNumberOfUpdates()); try { scores.updateScore("Bill", 13); } catch(Exception ex) { System.out.println("update failed for score 13"); } System.out.println("Number of updates: " + scores.getNumberOfUpdates()); for(String name : scores.getNames()) { System.out.println( String.format("Score for %s is %d", name, scores.getScore(name))); } } }结果:
Number of updates: 3 update failed for score 13 Number of updates: 3 Score for Joe is 14 Score for Bernie is 12 Score for Sally is 15解析: We first add scores for three players. Then we add another score value that will result in the transaction rollback. This last score update should have no effect. Finally, we iterate over the scores in the transactional map.