Hone logo
Hone
Problems

Implementing Transactional Memory in JavaScript

Transactional memory allows you to group a series of operations into a single atomic unit. If any operation within the transaction fails, all changes are rolled back, ensuring data consistency. This challenge asks you to implement a simplified transactional memory system in JavaScript, enabling you to perform multiple state updates as if they happened instantaneously.

Problem Description

You are tasked with creating a TransactionalMemory class in JavaScript. This class should provide a mechanism to group state updates within a transaction. The core functionality revolves around the run method, which accepts a function. This function represents the transaction's logic and can modify the internal state of the TransactionalMemory instance. The run method should:

  1. Begin a Transaction: Before executing the transaction function, save the current state of the object.
  2. Execute the Transaction: Execute the provided function.
  3. Commit or Rollback: If the transaction function completes successfully (doesn't throw an error), commit the changes made during the transaction. If the transaction function throws an error, rollback to the state saved before the transaction began.
  4. Return a Value: The run method should return the value returned by the transaction function.

The internal state of the TransactionalMemory is represented by a simple object. The transaction function can modify this object.

Examples

Example 1:

Input:
const tm = new TransactionalMemory({ a: 1, b: 2 });

tm.run(() => {
  tm.state.a = 10;
  tm.state.b = 20;
  return 42;
});

Output:
{ a: 10, b: 20 }

Explanation:
The transaction successfully modified the state. The `run` method returns 42.

Example 2:

Input:
const tm = new TransactionalMemory({ a: 1, b: 2 });

tm.run(() => {
  tm.state.a = 10;
  throw new Error("Transaction failed!");
});

Output:
{ a: 1, b: 2 }

Explanation:
The transaction failed due to an error. The state is rolled back to its original value.

Example 3: (Edge Case - Empty Transaction)

Input:
const tm = new TransactionalMemory({ a: 1, b: 2 });

tm.run(() => {
  return 123;
});

Output:
{ a: 1, b: 2 }

Explanation:
The transaction didn't modify the state, but it still needs to be wrapped in the transactional logic. The `run` method returns 123.

Constraints

  • The TransactionalMemory class should be implemented using JavaScript.
  • The internal state of the TransactionalMemory is a plain JavaScript object.
  • The transaction function can modify the internal state.
  • The run method must handle errors thrown by the transaction function by rolling back the state.
  • The run method must return the value returned by the transaction function.
  • The initial state of the TransactionalMemory is provided in the constructor.

Notes

  • Consider using try...catch blocks to handle errors within the run method.
  • Deep copying the state before and after the transaction is crucial for proper rollback. Using JSON.parse(JSON.stringify(obj)) is a simple way to achieve a deep copy, but be aware of its limitations (e.g., functions and circular references won't be copied). For more complex scenarios, consider a dedicated deep copy library.
  • This is a simplified implementation of transactional memory. Real-world transactional memory systems are significantly more complex and often involve concurrency control mechanisms.
  • Focus on the core functionality of committing or rolling back changes based on the success or failure of the transaction function.
class TransactionalMemory {
  constructor(initialState) {
    this.state = initialState;
  }

  run(transaction) {
    const previousState = JSON.parse(JSON.stringify(this.state)); // Deep copy

    try {
      const result = transaction();
      this.state = JSON.parse(JSON.stringify(this.state)); // Deep copy after modification
      return result;
    } catch (error) {
      this.state = previousState; // Rollback
      throw error; // Re-throw the error to propagate it
    }
  }
}
Loading editor...
javascript