Wenn ich eine Java-Klasse unterhalb definiert haben über Dependency Injection in meiner Web-Anwendung injiziert:Frühling Singleton Threadsicherheit
public AccountDao
{
private NamedParameterJdbcTemplate njt;
private List<Account> accounts;
public AccountDao(Datasource ds)
{
this.njt = new NamedParameterJdbcTemplate(ds);
refreshAccounts();
}
/*called at creation, and then via API calls to inform service new users have
been added to the database by a separate program*/
public void refreshAccounts()
{
this.accounts = /*call to database to get list of accounts*/
}
//called by every request to web service
public boolean isActiveAccount(String accountId)
{
Account a = map.get(accountId);
return a == null ? false : a.isActive();
}
}
Ich bin besorgt über die Thread-Sicherheit. Kann das Spring-Framework keine Fälle behandeln, in denen eine Anfrage von der Liste gelesen wird und sie gerade von einer anderen aktualisiert wird? Ich habe zuvor in anderen Anwendungen Lese-/Schreibsperren verwendet, aber ich habe nie zuvor über einen Fall wie oben nachgedacht.
Ich habe geplant, die Bohne als Singleton zur Verwendung, so konnte ich die Datenbanklast reduzieren.
By the way, ist dies ein Follow-up der folgenden Frage:
Java Memory Storage to Reduce Database Load - Safe?
EDIT:
So wie dieser Code würde dieses Problem lösen:
/*called at creation, and then via API calls to inform service new users have
been added to the database by a separate program*/
public void refreshAccounts()
{
//java.util.concurrent.locks.Lock
final Lock w = lock.writeLock();
w.lock();
try{
this.accounts = /*call to database to get list of accounts*/
}
finally{
w.unlock();
}
}
//called by every request to web service
public boolean isActiveAccount(String accountId)
{
final Lock r = lock.readLock();
r.lock();
try{
Account a = map.get(accountId);
}
finally{
r.unlock();
}
return a == null ? false : a.isActive();
}
Ok, Follow-up für die übernehmen: Ist das fixierbare leicht über den Code in dieser Java Klasse enthalten sind (oder Anwendungskontext Fixes), oder bin ich besser dran, für eine Zwischenspeicherung/Datenbanklösung geht? – thatidiotguy
Sie können eine temporäre Liste verwenden, um den Aufruf der Datenbank in 'refreshAccounts()' durchzuführen. Wenn dies der Fall ist, synchronisieren Sie sie auf "accounts" und weisen Sie sie dieser Liste zu. –
würde ich definitiv Caching/Datenbank sagen. Die Nebenläufigkeit selbst zu verwalten ist schwierig. Mit dem Caching können Sie sich zumindest die Gleichzeitigkeitskontrolle merken.Wenn Sie wirklich eine beliebige Anzahl von Anfragen haben wollten, würde ich den scope = prototype angeben. Dann stoßen Sie auf das Ladungsproblem, um das Sie besorgt waren. –