better transaction granularity

This commit is contained in:
Athou
2014-08-11 06:11:12 +02:00
parent b8cd0b024c
commit f83a7a2ef7
4 changed files with 54 additions and 66 deletions

View File

@@ -142,8 +142,8 @@ public class CommaFeedApplication extends Application<CommaFeedConfiguration> {
// Services // Services
ApplicationPropertiesService applicationPropertiesService = new ApplicationPropertiesService(); ApplicationPropertiesService applicationPropertiesService = new ApplicationPropertiesService();
DatabaseCleaningService cleaningService = new DatabaseCleaningService(feedDAO, feedEntryDAO, feedEntryContentDAO, DatabaseCleaningService cleaningService = new DatabaseCleaningService(sessionFactory, feedDAO, feedEntryDAO, feedEntryContentDAO,
feedEntryStatusDAO, feedSubscriptionDAO); feedEntryStatusDAO);
FeedEntryContentService feedEntryContentService = new FeedEntryContentService(feedEntryContentDAO); FeedEntryContentService feedEntryContentService = new FeedEntryContentService(feedEntryContentDAO);
FeedEntryService feedEntryService = new FeedEntryService(feedSubscriptionDAO, feedEntryDAO, feedEntryStatusDAO, cacheService); FeedEntryService feedEntryService = new FeedEntryService(feedSubscriptionDAO, feedEntryDAO, feedEntryStatusDAO, cacheService);
FeedEntryTagService feedEntryTagService = new FeedEntryTagService(feedEntryDAO, feedEntryTagDAO); FeedEntryTagService feedEntryTagService = new FeedEntryTagService(feedEntryDAO, feedEntryTagDAO);
@@ -202,8 +202,8 @@ public class CommaFeedApplication extends Application<CommaFeedConfiguration> {
// Tasks // Tasks
SchedulingService schedulingService = new SchedulingService(); SchedulingService schedulingService = new SchedulingService();
schedulingService.register(new OldStatusesCleanupTask(sessionFactory, config, cleaningService)); schedulingService.register(new OldStatusesCleanupTask(config, cleaningService));
schedulingService.register(new OrphansCleanupTask(sessionFactory, cleaningService)); schedulingService.register(new OrphansCleanupTask(cleaningService));
// Managed objects // Managed objects
environment.lifecycle().manage(startupService); environment.lifecycle().manage(startupService);

View File

@@ -1,7 +1,6 @@
package com.commafeed.backend.service; package com.commafeed.backend.service;
import java.util.Calendar; import java.util.Calendar;
import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@@ -9,15 +8,16 @@ import java.util.concurrent.TimeUnit;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.hibernate.SessionFactory;
import com.commafeed.backend.dao.FeedDAO; import com.commafeed.backend.dao.FeedDAO;
import com.commafeed.backend.dao.FeedEntryContentDAO; import com.commafeed.backend.dao.FeedEntryContentDAO;
import com.commafeed.backend.dao.FeedEntryDAO; import com.commafeed.backend.dao.FeedEntryDAO;
import com.commafeed.backend.dao.FeedEntryStatusDAO; import com.commafeed.backend.dao.FeedEntryStatusDAO;
import com.commafeed.backend.dao.FeedSubscriptionDAO; import com.commafeed.backend.dao.UnitOfWork;
import com.commafeed.backend.model.Feed; import com.commafeed.backend.model.Feed;
import com.commafeed.backend.model.FeedEntry; import com.commafeed.backend.model.FeedEntry;
import com.commafeed.backend.model.FeedEntryStatus; import com.commafeed.backend.model.FeedEntryStatus;
import com.commafeed.backend.model.FeedSubscription;
/** /**
* Contains utility methods for cleaning the database * Contains utility methods for cleaning the database
@@ -29,19 +29,24 @@ public class DatabaseCleaningService {
private static final int BATCH_SIZE = 100; private static final int BATCH_SIZE = 100;
private final SessionFactory sessionFactory;
private final FeedDAO feedDAO; private final FeedDAO feedDAO;
private final FeedEntryDAO feedEntryDAO; private final FeedEntryDAO feedEntryDAO;
private final FeedEntryContentDAO feedEntryContentDAO; private final FeedEntryContentDAO feedEntryContentDAO;
private final FeedEntryStatusDAO feedEntryStatusDAO; private final FeedEntryStatusDAO feedEntryStatusDAO;
private final FeedSubscriptionDAO feedSubscriptionDAO;
public long cleanEntriesWithoutSubscriptions() { public long cleanEntriesWithoutSubscriptions() {
log.info("cleaning entries without subscriptions"); log.info("cleaning entries without subscriptions");
long total = 0; long total = 0;
int deleted = 0; int deleted = 0;
do { do {
List<FeedEntry> entries = feedEntryDAO.findWithoutSubscriptions(BATCH_SIZE); deleted = new UnitOfWork<Integer>(sessionFactory) {
deleted = feedEntryDAO.delete(entries); @Override
protected Integer runInSession() throws Exception {
List<FeedEntry> entries = feedEntryDAO.findWithoutSubscriptions(BATCH_SIZE);
return feedEntryDAO.delete(entries);
}
}.run();
total += deleted; total += deleted;
log.info("removed {} entries without subscriptions", total); log.info("removed {} entries without subscriptions", total);
} while (deleted != 0); } while (deleted != 0);
@@ -54,8 +59,13 @@ public class DatabaseCleaningService {
long total = 0; long total = 0;
int deleted = 0; int deleted = 0;
do { do {
List<Feed> feeds = feedDAO.findWithoutSubscriptions(BATCH_SIZE); deleted = new UnitOfWork<Integer>(sessionFactory) {
deleted = feedDAO.delete(feeds); @Override
protected Integer runInSession() throws Exception {
List<Feed> feeds = feedDAO.findWithoutSubscriptions(BATCH_SIZE);
return feedDAO.delete(feeds);
};
}.run();
total += deleted; total += deleted;
log.info("removed {} feeds without subscriptions", total); log.info("removed {} feeds without subscriptions", total);
} while (deleted != 0); } while (deleted != 0);
@@ -68,7 +78,12 @@ public class DatabaseCleaningService {
long total = 0; long total = 0;
int deleted = 0; int deleted = 0;
do { do {
deleted = feedEntryContentDAO.deleteWithoutEntries(BATCH_SIZE); deleted = new UnitOfWork<Integer>(sessionFactory) {
@Override
protected Integer runInSession() throws Exception {
return feedEntryContentDAO.deleteWithoutEntries(BATCH_SIZE);
}
}.run();
total += deleted; total += deleted;
log.info("removed {} contents without entries", total); log.info("removed {} contents without entries", total);
} while (deleted != 0); } while (deleted != 0);
@@ -77,13 +92,18 @@ public class DatabaseCleaningService {
} }
public long cleanEntriesOlderThan(long value, TimeUnit unit) { public long cleanEntriesOlderThan(long value, TimeUnit unit) {
Calendar cal = Calendar.getInstance(); final Calendar cal = Calendar.getInstance();
cal.add(Calendar.MINUTE, -1 * (int) unit.toMinutes(value)); cal.add(Calendar.MINUTE, -1 * (int) unit.toMinutes(value));
long total = 0; long total = 0;
int deleted = 0; int deleted = 0;
do { do {
deleted = feedEntryDAO.delete(cal.getTime(), BATCH_SIZE); deleted = new UnitOfWork<Integer>(sessionFactory) {
@Override
protected Integer runInSession() throws Exception {
return feedEntryDAO.delete(cal.getTime(), BATCH_SIZE);
}
}.run();
total += deleted; total += deleted;
log.info("removed {} entries", total); log.info("removed {} entries", total);
} while (deleted != 0); } while (deleted != 0);
@@ -91,33 +111,21 @@ public class DatabaseCleaningService {
return total; return total;
} }
public void mergeFeeds(Feed into, List<Feed> feeds) { public long cleanStatusesOlderThan(final Date olderThan) {
for (Feed feed : feeds) {
if (into.getId().equals(feed.getId())) {
continue;
}
List<FeedSubscription> subs = feedSubscriptionDAO.findByFeed(feed);
for (FeedSubscription sub : subs) {
sub.setFeed(into);
}
feedSubscriptionDAO.saveOrUpdate(subs);
feedDAO.delete(feed);
}
feedDAO.saveOrUpdate(into);
}
public long cleanStatusesOlderThan(Date olderThan) {
log.info("cleaning old read statuses"); log.info("cleaning old read statuses");
long total = 0; long total = 0;
List<FeedEntryStatus> list = Collections.emptyList(); int deleted = 0;
do { do {
list = feedEntryStatusDAO.getOldStatuses(olderThan, BATCH_SIZE); deleted = new UnitOfWork<Integer>(sessionFactory) {
if (!list.isEmpty()) { @Override
feedEntryStatusDAO.delete(list); protected Integer runInSession() throws Exception {
total += list.size(); List<FeedEntryStatus> list = feedEntryStatusDAO.getOldStatuses(olderThan, BATCH_SIZE);
log.info("cleaned {} old read statuses", total); return feedEntryStatusDAO.delete(list);
} }
} while (!list.isEmpty()); }.run();
total += deleted;
log.info("cleaned {} old read statuses", total);
} while (deleted != 0);
log.info("cleanup done: {} old read statuses deleted", total); log.info("cleanup done: {} old read statuses deleted", total);
return total; return total;
} }

View File

@@ -5,32 +5,22 @@ import java.util.concurrent.TimeUnit;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.hibernate.SessionFactory;
import com.commafeed.CommaFeedConfiguration; import com.commafeed.CommaFeedConfiguration;
import com.commafeed.backend.dao.UnitOfWork;
import com.commafeed.backend.service.DatabaseCleaningService; import com.commafeed.backend.service.DatabaseCleaningService;
import com.commafeed.backend.task.SchedulingService.ScheduledTask; import com.commafeed.backend.task.SchedulingService.ScheduledTask;
@RequiredArgsConstructor @RequiredArgsConstructor
public class OldStatusesCleanupTask implements ScheduledTask { public class OldStatusesCleanupTask implements ScheduledTask {
private final SessionFactory sessionFactory;
private final CommaFeedConfiguration config; private final CommaFeedConfiguration config;
private final DatabaseCleaningService cleaner; private final DatabaseCleaningService cleaner;
@Override @Override
public void run() { public void run() {
new UnitOfWork<Void>(sessionFactory) { Date threshold = config.getApplicationSettings().getUnreadThreshold();
@Override if (threshold != null) {
protected Void runInSession() throws Exception { cleaner.cleanStatusesOlderThan(threshold);
Date threshold = config.getApplicationSettings().getUnreadThreshold(); }
if (threshold != null) {
cleaner.cleanStatusesOlderThan(threshold);
}
return null;
}
}.run();
} }
@Override @Override

View File

@@ -4,29 +4,19 @@ import java.util.concurrent.TimeUnit;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.hibernate.SessionFactory;
import com.commafeed.backend.dao.UnitOfWork;
import com.commafeed.backend.service.DatabaseCleaningService; import com.commafeed.backend.service.DatabaseCleaningService;
import com.commafeed.backend.task.SchedulingService.ScheduledTask; import com.commafeed.backend.task.SchedulingService.ScheduledTask;
@RequiredArgsConstructor @RequiredArgsConstructor
public class OrphansCleanupTask implements ScheduledTask { public class OrphansCleanupTask implements ScheduledTask {
private final SessionFactory sessionFactory;
private final DatabaseCleaningService cleaner; private final DatabaseCleaningService cleaner;
@Override @Override
public void run() { public void run() {
new UnitOfWork<Void>(sessionFactory) { cleaner.cleanEntriesWithoutSubscriptions();
@Override cleaner.cleanFeedsWithoutSubscriptions();
protected Void runInSession() throws Exception { cleaner.cleanContentsWithoutEntries();
cleaner.cleanEntriesWithoutSubscriptions();
cleaner.cleanFeedsWithoutSubscriptions();
cleaner.cleanContentsWithoutEntries();
return null;
}
}.run();
} }
@Override @Override