Skip to content

Commit

Permalink
Merge pull request #570 from ballerina-platform/revert-537-feature_tr…
Browse files Browse the repository at this point in the history
…ansaction_recovery

Revert "Logging for Transaction Recovery in a 2PC Transaction"
  • Loading branch information
gimantha authored Nov 13, 2024
2 parents 7b2f40c + 346b470 commit d4be2ed
Show file tree
Hide file tree
Showing 9 changed files with 16 additions and 120 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ puppycrawlCheckstyleVersion=10.12.0
group=org.ballerinalang
version=1.10.1-SNAPSHOT

ballerinaLangVersion=2201.11.0-20241011-144500-86ae40bf
ballerinaLangVersion=2201.10.0
stdlibIoVersion=1.6.1
stdlibConstraintVersion=1.5.0
stdlibOsVersion=1.8.0
Expand Down
50 changes: 11 additions & 39 deletions transaction-ballerina/2pc_transaction.bal
Original file line number Diff line number Diff line change
Expand Up @@ -44,28 +44,18 @@ class TwoPhaseCommitTransaction {
string|lang_trx:Error ret = "";

// Prepare local resource managers
writeToLog(transactionId, transactionBlockId, STATE_PREPARING);
boolean localPrepareSuccessful = prepareResourceManagers(self.transactionId, self.transactionBlockId);
if (!localPrepareSuccessful) {
log:printInfo("Local prepare failed, aborting..");
writeToLog(transactionId, transactionBlockId, STATE_ABORTING);
var result = self.notifyParticipants(COMMAND_ABORT, ());
if (result is error) {
writeToLog(transactionId, transactionBlockId, STATE_HAZARD);
return "hazard";
} else {
match result {
"committed" => {
writeToLog(transactionId, transactionBlockId, STATE_COMMITTED);
return "committed";
}
"aborted" => {
writeToLog(transactionId, transactionBlockId, STATE_ABORTED);
return "aborted";
}
"committed" => { return "committed"; }
"aborted" => { return "aborted"; }
}
}
writeToLog(transactionId, transactionBlockId, STATE_ABORTED);
return "aborted";
}

Expand All @@ -78,7 +68,6 @@ class TwoPhaseCommitTransaction {
if (prepareDurablesDecision == PREPARE_DECISION_COMMIT) {
// If all durable participants voted YES (PREPARED or READONLY), next call notify(commit) on all
// (durable & volatile) participants and return committed to the initiator
writeToLog(transactionId, transactionBlockId, STATE_COMMITTING);
var result = self.notifyParticipants(COMMAND_COMMIT, ());
if (result is error) {
// return Hazard outcome if a participant cannot successfully end its branch of the transaction
Expand All @@ -87,33 +76,26 @@ class TwoPhaseCommitTransaction {
boolean localCommitSuccessful = commitResourceManagers(self.transactionId, self.transactionBlockId);
if (!localCommitSuccessful) {
// "Local commit failed"
writeToLog(transactionId, transactionBlockId, STATE_HAZARD);
ret = prepareError(OUTCOME_HAZARD);
} else {
writeToLog(transactionId, transactionBlockId, STATE_COMMITTED);
ret = OUTCOME_COMMITTED;
}
}
} else {
// If some durable participants voted NO, next call notify(abort) on all participants
// and return aborted to the initiator
writeToLog(transactionId, transactionBlockId, STATE_ABORTING);
var result = self.notifyParticipants(COMMAND_ABORT, ());
if (result is error) {
// return Hazard outcome if a participant cannot successfully end its branch of the transaction
writeToLog(transactionId, transactionBlockId, STATE_HAZARD);
ret = prepareError(OUTCOME_HAZARD);
} else {
boolean localAbortSuccessful = abortResourceManagers(self.transactionId, self.transactionBlockId);
if (!localAbortSuccessful) {
writeToLog(transactionId, transactionBlockId, STATE_HAZARD);
ret = prepareError(OUTCOME_HAZARD);
} else {
if (self.possibleMixedOutcome) {
writeToLog(transactionId, transactionBlockId, STATE_MIXED);
ret = OUTCOME_MIXED;
} else {
writeToLog(transactionId, transactionBlockId, STATE_ABORTED);
ret = OUTCOME_ABORTED;
}
}
Expand All @@ -122,23 +104,18 @@ class TwoPhaseCommitTransaction {
} else {
// If some volatile participants voted NO, next call notify(abort) on all volatile articipants
// and return aborted to the initiator
writeToLog(transactionId, transactionBlockId, STATE_ABORTING);
var result = self.notifyParticipants(COMMAND_ABORT, PROTOCOL_VOLATILE);
if (result is error) {
// return Hazard outcome if a participant cannot successfully end its branch of the transaction
writeToLog(transactionId, transactionBlockId, STATE_HAZARD);
ret = prepareError(OUTCOME_HAZARD);
} else {
boolean localAbortSuccessful = abortResourceManagers(self.transactionId, self.transactionBlockId);
if (!localAbortSuccessful) {
writeToLog(transactionId, transactionBlockId, STATE_HAZARD);
ret = prepareError(OUTCOME_HAZARD);
} else {
if (self.possibleMixedOutcome) {
writeToLog(transactionId, transactionBlockId, STATE_MIXED);
ret = OUTCOME_MIXED;
} else {
writeToLog(transactionId, transactionBlockId, STATE_ABORTED);
ret = OUTCOME_ABORTED;
}
}
Expand Down Expand Up @@ -181,8 +158,8 @@ class TwoPhaseCommitTransaction {
while (i < participantArr.length()) {
var participant = participantArr[i];
i += 1;
//TODO: commenting due to a caching issue
//foreach var participant in self.participants {
//TODO: commenting due to a caching issue
//foreach var participant in self.participants {
future<[(PrepareResult|error)?, Participant]> f = @strand{thread:"any"} start participant.prepare(protocol);
results[results.length()] = f;
}
Expand All @@ -205,7 +182,7 @@ class TwoPhaseCommitTransaction {
string participantId = participant.participantId;
if (result is PrepareResult) {
if (result == PREPARE_RESULT_PREPARED) {
// All set for a PREPARE_DECISION_COMMIT so we can proceed without doing anything
// All set for a PREPARE_DECISION_COMMIT so we can proceed without doing anything
} else if (result == PREPARE_RESULT_COMMITTED) {
// If one or more participants returns "committed" and the overall prepare fails, we have to
// report a mixed-outcome to the initiator
Expand All @@ -215,14 +192,14 @@ class TwoPhaseCommitTransaction {
self.removeParticipant(participantId,
"Could not remove committed participant: " + participantId + " from transaction: " +
self.transactionId);
// All set for a PREPARE_DECISION_COMMIT so we can proceed without doing anything
// All set for a PREPARE_DECISION_COMMIT so we can proceed without doing anything
} else if (result == PREPARE_RESULT_READ_ONLY) {
// Don't send notify to this participant because it is read-only.
// We can forget about this participant.
self.removeParticipant(participantId,
"Could not remove read-only participant: " + participantId + " from transaction: " +
self.transactionId);
// All set for a PREPARE_DECISION_COMMIT so we can proceed without doing anything
// All set for a PREPARE_DECISION_COMMIT so we can proceed without doing anything
} else if (result == PREPARE_RESULT_ABORTED) {
// Remove the participant who sent the abort since we don't want to do a notify(Abort) to that
// participant
Expand All @@ -249,17 +226,17 @@ class TwoPhaseCommitTransaction {
while (i < participantArr.length()) {
var participant = participantArr[i];
i += 1;
//TODO: commenting due to a caching issue
//foreach var participant in self.participants {
//TODO: commenting due to a caching issue
//foreach var participant in self.participants {
future<(NotifyResult|error)?> f = @strand{thread:"any"} start participant.notify(action, protocolName);
results[results.length()] = f;
}
int j = 0;
while (j < results.length()) {
var r = results[j];
j += 1;
//TODO: commenting due to a caching issue
//foreach var r in results {
//TODO: commenting due to a caching issue
//foreach var r in results {
future<(NotifyResult|error)?> f;
if (r is future<(NotifyResult|error)?>) {
f = r;
Expand All @@ -279,24 +256,19 @@ class TwoPhaseCommitTransaction {
function abortInitiatorTransaction() returns string|lang_trx:Error {
log:printInfo("Aborting initiated transaction: " + self.transactionId + ":" + self.transactionBlockId);
string|lang_trx:Error ret = "";
writeToLog(self.transactionId, self.transactionBlockId, STATE_ABORTING);
// return response to the initiator. ( Aborted | Mixed )
var result = self.notifyParticipants(COMMAND_ABORT, ());
if (result is error) {
// return Hazard outcome if a participant cannot successfully end its branch of the transaction
writeToLog(self.transactionId, self.transactionBlockId, STATE_HAZARD);
ret = prepareError(OUTCOME_HAZARD);
} else {
boolean localAbortSuccessful = abortResourceManagers(self.transactionId, self.transactionBlockId);
if (!localAbortSuccessful) {
writeToLog(self.transactionId, self.transactionBlockId, STATE_HAZARD);
ret = prepareError(OUTCOME_HAZARD);
} else {
if (self.possibleMixedOutcome) {
writeToLog(self.transactionId, self.transactionBlockId, STATE_MIXED);
ret = OUTCOME_MIXED;
} else {
writeToLog(self.transactionId, self.transactionBlockId, STATE_ABORTED);
ret = OUTCOME_ABORTED;
}
}
Expand Down
4 changes: 2 additions & 2 deletions transaction-ballerina/Ballerina.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ graalvmCompatible = true

[[platform.java17.dependency]]
artifactId = "transaction"
version = "1.11.0-SNAPSHOT"
path = "../transaction-native/build/libs/transaction-native-1.11.0-SNAPSHOT.jar"
version = "1.10.0"
path = "../transaction-native/build/libs/transaction-native-1.10.0.jar"
groupId = "ballerina"
4 changes: 2 additions & 2 deletions transaction-ballerina/Dependencies.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

[ballerina]
dependencies-toml-version = "2"
distribution-version = "2201.11.0-SNAPSHOT"
distribution-version = "2201.10.0"

[[package]]
org = "ballerina"
Expand Down Expand Up @@ -315,7 +315,7 @@ modules = [
[[package]]
org = "ballerina"
name = "time"
version = "2.5.0"
version = "2.4.0"
dependencies = [
{org = "ballerina", name = "jballerina.java"}
]
Expand Down
5 changes: 0 additions & 5 deletions transaction-ballerina/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -89,16 +89,11 @@ publishing {
}
}

task cleanUpLogsBeforeTest {
delete "$project.projectDir/target/transactionLogs"
}

updateTomlFiles.dependsOn copyStdlibs

build.dependsOn ":transaction-native:build"
build.dependsOn ":transaction-ballerina:generatePomFileForMavenPublication"
test.dependsOn ":transaction-native:build"
test.dependsOn ":transaction-ballerina:cleanUpLogsBeforeTest"

publishToMavenLocal.dependsOn build
publish.dependsOn build
10 changes: 0 additions & 10 deletions transaction-ballerina/constants.bal
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,5 @@ const string OUTCOME_HAZARD = "hazard";

const string TRANSACTION_UNKNOWN = "Transaction-Unknown";

// Recovery Log States (Write-Ahead Logging)
const string STATE_PREPARING = "PREPARING";
const string STATE_COMMITTING = "COMMITTING";
const string STATE_ABORTING = "ABORTING";
const string STATE_COMMITTED = "COMMITTED";
const string STATE_ABORTED = "ABORTED";
const string STATE_HAZARD = "HAZARD";
const string STATE_MIXED = "MIXED";
const string STATE_TERMINATED = "TERMINATED";

configurable string coordinatorHost = getHostAddress();
configurable int coordinatorPort = getAvailablePort();
10 changes: 0 additions & 10 deletions transaction-ballerina/internal.bal
Original file line number Diff line number Diff line change
Expand Up @@ -225,13 +225,3 @@ function getTransactionCleanupTimeout() returns int = @java:Method {
'class: "org.ballerinalang.stdlib.transaction.Utils",
name: "getTransactionCleanupTimeout"
} external;

function writeToLog(string trxId, string transactionBlockId, string transactionStatus) = @java:Method {
'class: "org.ballerinalang.stdlib.transaction.TransactionRecovery",
name: "writeToLog"
} external;

function startupCrashRecovery() = @java:Method {
'class: "org.ballerinalang.stdlib.transaction.TransactionRecovery",
name: "startupCrashRecovery"
} external;
4 changes: 0 additions & 4 deletions transaction-ballerina/tests/Config.toml
Original file line number Diff line number Diff line change
@@ -1,4 +0,0 @@
[ballerina.lang.transaction]
recoveryLogDir="./target/transactionLogs"
recoveryLogName="testLogs"
checkpointInterval=-1

This file was deleted.

0 comments on commit d4be2ed

Please sign in to comment.