MyBatisConfBuilder(Database database) {
this.conf = new Configuration();
this.conf.setEnvironment(new Environment("production", createTransactionFactory(), database.getDataSource()));
- this.conf.setUseGeneratedKeys(true);
+ this.conf.setUseGeneratedKeys(false);
this.conf.setLazyLoadingEnabled(false);
this.conf.setJdbcTypeForNull(JdbcType.NULL);
Dialect dialect = database.getDialect();
package org.sonar.db;
import org.apache.ibatis.session.Configuration;
-import org.hamcrest.core.Is;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.sonar.db.rule.RuleMapper;
-import static org.hamcrest.CoreMatchers.notNullValue;
-import static org.junit.Assert.assertThat;
+import static org.assertj.core.api.Assertions.assertThat;
+
public class MyBatisTest {
private static SQDatabase database;
underTest.start();
Configuration conf = underTest.getSessionFactory().getConfiguration();
- assertThat(conf.isUseGeneratedKeys(), Is.is(true));
- assertThat(conf.hasMapper(RuleMapper.class), Is.is(true));
- assertThat(conf.isLazyLoadingEnabled(), Is.is(false));
+
+ assertThat(conf.isUseGeneratedKeys()).isFalse();
+ assertThat(conf.hasMapper(RuleMapper.class)).isTrue();
+ assertThat(conf.isLazyLoadingEnabled()).isFalse();
}
@Test
underTest.start();
try (DbSession session = underTest.openSession(false)) {
- assertThat(session.getConnection(), notNullValue());
- assertThat(session.getMapper(RuleMapper.class), notNullValue());
+ assertThat(session.getConnection()).isNotNull();
+ assertThat(session.getMapper(RuleMapper.class)).isNotNull();
}
}
}
@Test
public void selectData_returns_absent_if_uuid_exists_but_data_is_null() {
insertData(A_UUID);
- dbTester.commit();
Optional<DbInputStream> result = underTest.selectData(dbTester.getSession(), A_UUID);
assertThat(result).isNotPresent();
private void insertData(String uuid) {
dbTester.executeInsert(TABLE_NAME, "task_uuid", uuid, "created_at", NOW, "updated_at", NOW);
- dbTester.commit();
}
}
import java.util.Map;
import java.util.Random;
import java.util.Set;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;
+import java.util.stream.IntStream;
import java.util.stream.Stream;
import org.jetbrains.annotations.NotNull;
import org.sonar.api.measures.CoreMetrics;
private static final long NUMBER_OF_USERS = 100_000L;
- public static void main(String[] args) {
+ public static void main(String[] args) throws InterruptedException {
+ final DbTester dbTester = createDbTester();
+
// read base data
final Map<String, MetricDto> metricDtosByKey;
final List<ProjectDto> allProjects;
final List<PortfolioDto> allPortfolios;
final Set<RuleDto> enabledRules;
- DbSession dbSession = dbTester.getSession();
- metricDtosByKey = dbTester.getDbClient().metricDao().selectAll(dbSession).stream().collect(
- Collectors.toMap(MetricDto::getKey, Function.identity()));
- allProjects = dbTester.getDbClient().projectDao().selectProjects(dbSession);
- allPortfolios = dbTester.getDbClient().portfolioDao().selectAll(dbSession);
+ DbSession initSession = dbTester.getSession();
+ metricDtosByKey = dbTester.getDbClient().metricDao().selectAll(initSession).stream().collect(
+ Collectors.toMap(MetricDto::getKey, Function.identity())
+ );
+ allProjects = dbTester.getDbClient().projectDao().selectProjects(initSession);
+ allPortfolios = dbTester.getDbClient().portfolioDao().selectAll(initSession);
enabledRules = new HashSet<>(dbTester.getDbClient().ruleDao().selectEnabled(dbTester.getSession()));
- ProjectDto projectDto = generateProject(new SqContext(enabledRules, metricDtosByKey, dbTester),
- new ProjectStructure("project " + (allProjects.size() + 1), 10, 10, 10, 2, 5));
- allProjects.add(projectDto);
+ ExecutorService executorService = Executors.newFixedThreadPool(1);
+ SqContext sqContext = new SqContext(enabledRules, metricDtosByKey, dbTester);
- createUsers(allProjects);
+ IntStream.rangeClosed(1, 1)
+ .map(i -> i + allProjects.size())
+ .mapToObj(i -> new ProjectStructure("project " + i, 10, 100, 10, 2, 5))
+ .forEach(projectStructure -> {
+ executorService.submit(() -> {
+ sqContext.dbTester.getSession(true);
+ generateProject(
+ sqContext, projectStructure
+ );
+ });
+ });
+ executorService.shutdown();
+ executorService.awaitTermination(100, TimeUnit.DAYS);
+
+ createUsers(allProjects);
allPortfolios.addAll(createPortfolios(new PortfolioGenerationSettings(allPortfolios.size(), 100, 10), allProjects));
// close database connection
private static ProjectDto generateProject(SqContext sqContext, ProjectStructure pj) {
ComponentDto projectCompoDto = sqContext.dbTester.components().insertPublicProject(p -> p.setName(pj.projectName));
+ sqContext.dbTester.forceCommit();
ProjectDto projectDto = sqContext.dbTester.components().getProjectDto(projectCompoDto);
Streams.concat(
SnapshotDto lastSnapshotDto = snapshots.get(0);
lastSnapshotDto.setLast(true);
sqContext.dbTester.components().insertSnapshots(snapshots.toArray(new SnapshotDto[0]));
+ sqContext.dbTester.forceCommit();
});
return projectDto;
.mapToObj(i -> toNotificationQueueDto(new Notification("foo_" + i)))
.collect(toList());
dao.insert(notifs);
- db.commit();
List<String> uuids = selectAllUuid();
.mapToObj(i -> toNotificationQueueDto(new Notification("foo_" + i)))
.collect(toList());
dao.insert(notifs);
- db.commit();
assertThat(dao.selectOldest(3))
.extracting(NotificationQueueDto::getData)
"removed", removed,
"created_at", createdAt,
"updated_at", updatedAt);
- db.commit();
}
}
import java.util.Map;
import java.util.stream.Stream;
import javax.annotation.Nullable;
+import org.jetbrains.annotations.NotNull;
import org.sonar.api.utils.System2;
import org.sonar.core.util.UuidFactory;
import org.sonar.core.util.UuidFactoryFast;
private final System2 system2;
private final AuditPersister auditPersister;
private DbClient client;
- ThreadLocal<DbSession> session = new ThreadLocal<>();
+ ThreadLocal<DbSessionContext> session = new ThreadLocal<>();
private final UserDbTester userTester;
private final ComponentDbTester componentTester;
private final ProjectLinkDbTester componentLinkTester;
@Override
protected void after() {
if (session.get() != null) {
- session.get().rollback();
- session.get().close();
+ session.get().dbSession.rollback();
+ session.get().dbSession.close();
session.remove();
}
db.stop();
}
public DbSession getSession() {
+ return getSession(false);
+ }
+
+ public DbSession getSession(boolean batched) {
if (session.get() == null) {
- session.set(db.getMyBatis().openSession(false));
+ session.set(new DbSessionContext(db.getMyBatis().openSession(batched), batched));
}
- return session.get();
+ return session.get().dbSession;
+ }
+
+ public void forceCommit() {
+ getSession().commit(true);
}
public void commit() {
- getSession().commit();
+ if(session.get() != null && !session.get().isBatched) {
+ getSession().commit();
+ }
}
public DbClient getDbClient() {
return ((HikariDataSource) db.getDatabase().getDataSource()).getJdbcUrl();
}
+ private record DbSessionContext(@NotNull DbSession dbSession, boolean isBatched){}
+
private static class DbSessionConnectionSupplier implements ConnectionSupplier {
private final DbSession dbSession;
public DbTesterMyBatisConfExtension(Class<?> firstMapperClass, Class<?>... otherMapperClasses) {
this.mapperClasses = Stream.concat(
- Stream.of(firstMapperClass),
- Arrays.stream(otherMapperClasses))
+ Stream.of(firstMapperClass),
+ Arrays.stream(otherMapperClasses))
.sorted(Comparator.comparing(Class::getName))
.toArray(Class<?>[]::new);
}