Use hibernate second-level cache when loading card sets on initial page load. Room for improvement here by using a more production-ready cache provider, but the immediate need is to not crash the database server under crush load.

This commit is contained in:
Andy Janata 2015-02-28 11:58:47 -08:00
parent 768f8f5a0a
commit 7a574d39b8
6 changed files with 47 additions and 10 deletions

View File

@ -21,3 +21,16 @@ hibernate.password=CorrectHorseBatteryStaple
# debugging information
hibernate.sql.show=false
hibernate.sql.format=false
# second-level hibernate cache.
# vastly reduces database load at expense of data potentially being stale.
# use an in-memory cache provider. this is not suitable for long-term use, however I am using it for
# my servers for the time being -- better than nothing
#hibernate.cache.use_second_level_cache=true
#hibernate.cache.use_query_cache=true
#hibernate.cache.provider_class=org.hibernate.cache.HashtableCacheProvider
# to turn it off, use these settings instead. you will hit the db a lot more often.
hibernate.cache.use_second_level_cache=false
hibernate.cache.use_query_cache=false
hibernate.cache.provider_class=org.hibernate.cache.NoCacheProvider

View File

@ -10,6 +10,10 @@
<property name="hibernate.connection.username">${hibernate.username}</property>
<property name="hibernate.connection.password">${hibernate.password}</property>
<property name="transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property>
<property name="hibernate.cache.use_second_level_cache">${hibernate.cache.use_second_level_cache}</property>
<property name="hibernate.cache.provider_class">${hibernate.cache.provider_class}</property>
<property name="hibernate.cache.use_query_cache">${hibernate.cache.use_query_cache}</property>
<property name="show_sql">${hibernate.sql.show}</property>
<property name="format_sql">${hibernate.sql.format}</property>

View File

@ -1,16 +1,16 @@
/**
* Copyright (c) 2012, Andy Janata
* All rights reserved.
*
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
*
* * Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided
* with the distribution.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
@ -23,6 +23,7 @@
package net.socialgamer.cah.db;
import javax.persistence.Cacheable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@ -30,14 +31,19 @@ import javax.persistence.Table;
import net.socialgamer.cah.data.BlackCard;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
/**
* A Black Card. Cards are persisted in a database and loaded with Hibernate.
*
*
* @author Andy Janata (ajanata@socialgamer.net)
*/
@Entity
@Table(name = "black_cards")
@Cacheable
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class PyxBlackCard extends BlackCard {
@Id

View File

@ -4,6 +4,7 @@ import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.persistence.Cacheable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@ -16,12 +17,16 @@ import net.socialgamer.cah.Constants.CardSetData;
import net.socialgamer.cah.data.CardSet;
import org.hibernate.Session;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.annotations.LazyCollection;
import org.hibernate.annotations.LazyCollectionOption;
@Entity
@Table(name = "card_set")
@Cacheable
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class PyxCardSet extends CardSet {
@Id
@ -40,6 +45,7 @@ public class PyxCardSet extends CardSet {
joinColumns = { @JoinColumn(name = "card_set_id") },
inverseJoinColumns = { @JoinColumn(name = "black_card_id") })
@LazyCollection(LazyCollectionOption.TRUE)
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private final Set<PyxBlackCard> blackCards;
@ManyToMany
@ -48,6 +54,7 @@ public class PyxCardSet extends CardSet {
joinColumns = { @JoinColumn(name = "card_set_id") },
inverseJoinColumns = { @JoinColumn(name = "white_card_id") })
@LazyCollection(LazyCollectionOption.TRUE)
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private final Set<PyxWhiteCard> whiteCards;
public PyxCardSet() {
@ -124,11 +131,11 @@ public class PyxCardSet extends CardSet {
final Map<CardSetData, Object> cardSetData = getCommonClientMetadata();
final Number blackCount = (Number) hibernateSession
.createQuery("select count(*) from PyxCardSet cs join cs.blackCards where cs.id = :id")
.setParameter("id", id).uniqueResult();
.setParameter("id", id).setCacheable(true).uniqueResult();
cardSetData.put(CardSetData.BLACK_CARDS_IN_DECK, blackCount);
final Number whiteCount = (Number) hibernateSession
.createQuery("select count(*) from PyxCardSet cs join cs.whiteCards where cs.id = :id")
.setParameter("id", id).uniqueResult();
.setParameter("id", id).setCacheable(true).uniqueResult();
cardSetData.put(CardSetData.WHITE_CARDS_IN_DECK, whiteCount);
return cardSetData;
}

View File

@ -1,16 +1,16 @@
/**
* Copyright (c) 2012, Andy Janata
* All rights reserved.
*
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
*
* * Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided
* with the distribution.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
@ -23,6 +23,7 @@
package net.socialgamer.cah.db;
import javax.persistence.Cacheable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@ -30,14 +31,19 @@ import javax.persistence.Table;
import net.socialgamer.cah.data.WhiteCard;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
/**
* A white Card. Cards are persisted in a database and loaded with Hibernate.
*
*
* @author Andy Janata (ajanata@socialgamer.net)
*/
@Entity
@Table(name = "white_cards")
@Cacheable
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class PyxWhiteCard extends WhiteCard {
@Id

View File

@ -98,6 +98,7 @@ public class FirstLoadHandler extends Handler {
final List<PyxCardSet> cardSets = hibernateSession
.createQuery(PyxCardSet.getCardsetQuery(includeInactiveCardsetsProvider.get()))
.setReadOnly(true)
.setCacheable(true)
.list();
final List<Map<CardSetData, Object>> cardSetsData =
new ArrayList<Map<CardSetData, Object>>(cardSets.size());