Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better control over read or write transactions. #165

Merged
merged 2 commits into from
Jan 18, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,14 @@
public interface MagmaCoreDatabase {

/**
* Start a transaction in READ mode and which will switch to WRITE if an update is attempted but
* only if no intermediate transaction has performed an update.
* Start a transaction in READ mode.
*/
void begin();
void beginRead();

/**
* Start a transaction in Write mode.
*/
void beginWrite();

/**
* Commit a transaction - Finish the current transaction and make any changes permanent (if a
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import org.apache.jena.query.QueryFactory;
import org.apache.jena.query.QuerySolution;
import org.apache.jena.query.ResultSet;
import org.apache.jena.query.TxnType;
import org.apache.jena.rdf.model.Literal;
import org.apache.jena.rdf.model.Model;
import org.apache.jena.rdf.model.ModelFactory;
Expand Down Expand Up @@ -114,9 +115,21 @@ public void register(final IriBase base) {
* {@inheritDoc}
*/
@Override
public void begin() {
public void beginRead() {
if (!dataset.isInTransaction()) {
dataset.begin();
dataset.begin(TxnType.READ);
} else {
throw new IllegalStateException("Already in a transaction");
}
}

/**
* {@inheritDoc}
*/
@Override
public void beginWrite() {
if (!dataset.isInTransaction()) {
dataset.begin(TxnType.WRITE);
} else {
throw new IllegalStateException("Already in a transaction");
}
Expand Down Expand Up @@ -426,7 +439,7 @@ public final List<Thing> toTopObjects(final QueryResultList queryResultsList) {
*/
@Override
public void dump(final PrintStream out) {
begin();
beginRead();
final Model model = dataset.getDefaultModel();
final StmtIterator statements = model.listStatements();

Expand All @@ -444,7 +457,7 @@ public void dump(final PrintStream out) {
* @param language RDF language syntax to output data as.
*/
public final void dump(final PrintStream out, final Lang language) {
begin();
beginRead();
RDFDataMgr.write(out, dataset.getDefaultModel(), language);
abort();
}
Expand All @@ -456,7 +469,7 @@ public final void dump(final PrintStream out, final Lang language) {
* @param language RDF language syntax to output data as.
*/
public final void load(final InputStream in, final Lang language) {
begin();
beginWrite();
final Model model = dataset.getDefaultModel();
RDFDataMgr.read(model, in, language);
commit();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,19 @@ public MagmaCoreRemoteSparqlDatabase(final String serviceUrl, final Dataset data
/**
* {@inheritDoc}
*/
public final void begin() {
public final void beginRead() {
if (!connection.isInTransaction()) {
connection.begin(TxnType.READ);
} else {
throw new IllegalStateException("Already in a transaction");
}
}

/**
* {@inheritDoc}
*/
public final void beginWrite() {
if (!connection.isInTransaction()) {
// The default TxnType.READ_PROMOTE is not supported.
connection.begin(TxnType.WRITE);
} else {
throw new IllegalStateException("Already in a transaction");
Expand Down Expand Up @@ -431,7 +441,7 @@ public final void dump(final PrintStream out, final Lang language) {
* @param language RDF language syntax to output data as.
*/
public final void load(final InputStream in, final Lang language) {
begin();
beginWrite();
final Dataset dataset = connection.fetchDataset();
final Model model = dataset.getDefaultModel();
RDFDataMgr.read(model, in, language);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -709,7 +709,7 @@ public Thing get(final IRI iri) {
*/
public Thing getInTransaction(final IRI iri) {
try {
database.begin();
database.beginRead();
final Thing result = database.get(iri);
database.commit();
return result;
Expand All @@ -724,9 +724,25 @@ public Thing getInTransaction(final IRI iri) {
*
* @param func {@link Function} to run.
*/
public void runInTransaction(final Function<MagmaCoreService, MagmaCoreService> func) {
public void runInReadTransaction(final Function<MagmaCoreService, MagmaCoreService> func) {
GCHQDeveloper42 marked this conversation as resolved.
Show resolved Hide resolved
try {
database.begin();
database.beginRead();
func.apply(this);
database.commit();
} catch (final Exception e) {
database.abort();
throw e;
}
}

/**
* Run a {@link Function} in a transaction.
*
* @param func {@link Function} to run.
*/
public void runInWriteTransaction(final Function<MagmaCoreService, MagmaCoreService> func) {
try {
database.beginWrite();
func.apply(this);
database.commit();
} catch (final Exception e) {
Expand All @@ -743,7 +759,7 @@ public void runInTransaction(final Function<MagmaCoreService, MagmaCoreService>
*/
public Map<String, Thing> findByEntityNameInTransaction(final List<String> entityNames) {
try {
database.begin();
database.beginRead();
final HashMap<String, Thing> result = new HashMap<String, Thing>();

for (final String name : entityNames) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -586,7 +586,7 @@ public class DataIntegrityReport {
* @return A {@link List} of {@link Thing} that represent data integrity errors.
*/
public static List<Thing> verify(final MagmaCoreDatabase db) {
db.begin();
db.beginRead();

final List<Thing> errors = new ArrayList<>();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ static void createAssociationPattern(final MagmaCoreDatabase db) {
community.addValue(HQDM.PARTICIPANT_IN, repBySign2Iri);

// Persist all objects
db.begin();
db.beginWrite();

db.create(userAssociationKind);
db.create(managerKind);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public void testCreateSuccess() {

// Convert the new Thing to a DbTransformation and use it to persist the Thing.
final DbTransformation transformation = svc.createDbTransformation(List.of(newThing));
svc.runInTransaction(transformation);
svc.runInWriteTransaction(transformation);

// Retrieve the Thing and make sure it matches the original.
final Map<String, Thing> foundThings = svc.findByEntityNameInTransaction(List.of(TEST_ENTITY_NAME));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public void testFindSuccess() {
now.addValue(HQDM.ENTITY_NAME, Instant.now().toString());

// Find the required Things by sign in a transaction.
db.begin();
db.beginRead();
final List<? extends Thing> participants = service
.findByKindOfAssociation(AssociationPatternTestData.userAssociationKindIri, now);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public void testFindSuccess() {
now.addValue(HQDM.ENTITY_NAME, Instant.now().toString());

// Find the required Things by sign in a transaction.
db.begin();
db.beginRead();
final List<? extends Thing> things = service.findByTypeKindAndSignPattern(
HQDM.PERSON,
SignPatternTestData.kindOfPersonIri,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public void testFindParticipantDetailsSuccess() throws MagmaCoreException {
now.addValue(HQDM.ENTITY_NAME, Instant.now().toString());

// Find the required Things by sign in a transaction.
db.begin();
db.beginRead();
final Set<ParticipantDetails> found1 = service.findParticipantDetails(
AssociationPatternTestData.person1,
AssociationPatternTestData.system1,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,17 +55,17 @@ public void test() {

individual.addValue(HQDM.MEMBER_OF, "classOfIndividual");

database.begin();
database.beginWrite();
database.create(individual);
database.commit();

individual.removeValue(HQDM.MEMBER_OF, "classOfIndividual");

database.begin();
database.beginWrite();
database.update(individual);
database.commit();

database.begin();
database.beginRead();
final Thing individualFromDb = database.get(individualIri);
database.commit();

Expand Down Expand Up @@ -95,7 +95,7 @@ public void testFindBySignSuccess() throws MagmaCoreException {
now.addValue(HQDM.ENTITY_NAME, Instant.now().toString());

// Find the required Things by sign in a transaction.
db.begin();
db.beginRead();
final List<? extends Thing> found1 = service.findBySignValue(SignPatternTestData.community1,
SignPatternTestData.pattern1, "person1", now);
final List<? extends Thing> found2 = service.findBySignValue(SignPatternTestData.community2,
Expand Down Expand Up @@ -143,7 +143,7 @@ public void testFindBySignWithNullSignValue() throws MagmaCoreException {
now.addValue(HQDM.ENTITY_NAME, Instant.now().toString());

// Find the required Things by sign in a transaction.
db.begin();
db.beginRead();
final List<? extends Thing> found = service.findBySignValue(SignPatternTestData.community1,
SignPatternTestData.pattern1, null, now);
db.commit();
Expand All @@ -170,7 +170,7 @@ public void testFindBySignWithBadPointInTime() throws MagmaCoreException {
final PointInTime now = SpatioTemporalExtentServices.createPointInTime("now");

// Find the required Things by sign in a transaction.
db.begin();
db.beginRead();
final List<? extends Thing> found = service.findBySignValue(SignPatternTestData.community1,
SignPatternTestData.pattern1, "person1", now);
db.commit();
Expand All @@ -197,14 +197,14 @@ public void testFindByPredicateOnly() {
individual2.addValue(RDFS.RDF_TYPE, HQDM.INDIVIDUAL);

// Create two objects.
svc.runInTransaction(mc -> {
svc.runInWriteTransaction(mc -> {
mc.create(individual1);
mc.create(individual2);
return mc;
});

// Find individual2 since it's the only one with MEMBER_OF_KIND
svc.runInTransaction(mc -> {
svc.runInReadTransaction(mc -> {
final List<Thing> result = mc.findByPredicateIriOnly(HQDM.MEMBER_OF_KIND);

assertEquals(1, result.size());
Expand All @@ -213,7 +213,7 @@ public void testFindByPredicateOnly() {
});

// Find both individuals by RDF_TYPE IRI object.
svc.runInTransaction(mc -> {
svc.runInReadTransaction(mc -> {
final List<Thing> result = mc.findByPredicateIriAndValue(RDFS.RDF_TYPE, HQDM.INDIVIDUAL);

assertEquals(2, result.size());
Expand All @@ -224,7 +224,7 @@ public void testFindByPredicateOnly() {
});

// Find individual1 by a String value
svc.runInTransaction(mc -> {
svc.runInReadTransaction(mc -> {
final List<Thing> result = mc.findByPredicateIriAndValue(HQDM.MEMBER_OF, "classOfIndividual");

assertEquals(1, result.size());
Expand Down Expand Up @@ -252,7 +252,7 @@ public void testFindByPartialSignAndClassCaseInsensitive() throws MagmaCoreExcep
now.addValue(HQDM.ENTITY_NAME, Instant.now().toString());

// Find the required Things by sign in a transaction.
db.begin();
db.beginRead();
final List<? extends Thing> found1 = service.findByPartialSignAndClass(
"person1", SignPatternTestData.classOfPersonIri, now);
final List<? extends Thing> found2 = service.findByPartialSignAndClass(
Expand Down Expand Up @@ -290,7 +290,7 @@ public void testFindByPartialSignAndClassCaseSensitive() throws MagmaCoreExcepti
now.addValue(HQDM.ENTITY_NAME, Instant.now().toString());

// Find the required Things by sign in a transaction.
db.begin();
db.beginRead();
final List<? extends Thing> found1 = service.findByPartialSignAndClassCaseSensitive(
"Person1", SignPatternTestData.classOfPersonIri, now);
final List<? extends Thing> found2 = service.findByPartialSignAndClassCaseSensitive(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ static void createSignPattern(final MagmaCoreDatabase db) {
stateOfSign2.addValue(HQDM.PARTICIPANT_IN, new IRI(repBySign2.getId()));

// Persist all objects
db.begin();
db.beginWrite();

db.create(community1);
db.create(community2);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public void testApplyAndInvert() {
new DbCreateOperation(individualIri, HQDM.PART_OF_POSSIBLE_WORLD, possibleWorldIri)));

// Apply the operations to the dataset.
mcService.runInTransaction(createIndividual);
mcService.runInWriteTransaction(createIndividual);

// Find the individual and assert values are present.
final Thing individual = mcService.getInTransaction(individualIri);
Expand All @@ -66,7 +66,7 @@ public void testApplyAndInvert() {
assertTrue(individual.hasThisValue(HQDM.PART_OF_POSSIBLE_WORLD, possibleWorldIri));

// Invert the operations and apply them in reverse order.
mcService.runInTransaction(DbChangeSet.invert(createIndividual));
mcService.runInWriteTransaction(DbChangeSet.invert(createIndividual));

assertNull(mcService.getInTransaction(individualIri));
}
Expand Down
Loading