> ## Documentation Index
> Fetch the complete documentation index at: https://alan-ramirez-dev.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# ⚖️ Consistencia ACID y Concurrencia

> Estrategias de aislamiento transaccional y protección contra Race Conditions.

El motor transaccional simula operaciones Fintech de alta fidelidad. Al manejar balances monetarios e intercambios de divisas, el sistema no puede permitirse inconsistencias numéricas ni pérdidas de datos causadas por peticiones simultáneas (Race Conditions).

Para resolver esto, la arquitectura se apoya firmemente en las propiedades **ACID** mediante el uso de bloqueos a nivel de persistencia en la base de datos relacional.

## 🔒 Bloqueo Pesimista (Pessimistic Locking)

Cuando dos procesos intentan modificar el balance del mismo usuario al mismo tiempo (por ejemplo, una inyección de capital y una compra de USDC simultáneas), una aproximación tradicional podría causar una "lectura sucia" o una pérdida de actualización.

La API mitiga este riesgo implementando un **Bloqueo Pesimista de Escritura** (`PESSIMISTIC_WRITE`) a través de Spring Data JPA. Esto instruye a PostgreSQL a ejecutar una cláusula `SELECT ... FOR UPDATE`, congelando la fila del usuario en la base de datos hasta que la transacción HTTP actual termine por completo.

```java theme={null}
// Definición del bloqueo en PortafolioRepository.java
@Repository
public interface PortafolioRepository extends JpaRepository<Portafolio, Long> {

    @Lock(LockModeType.PESSIMISTIC_WRITE)
    @Query("SELECT p FROM Portafolio p WHERE p.usuarioId = :usuarioId")
    Optional<Portafolio> findByUsuarioIdForUpdate(@Param("usuarioId") Long usuarioId);
}
```

## 🧮 Aritmética de Alta Precisión (BigDecimal)

El segundo pilar de la consistencia en el motor financiero es el control estricto sobre el cálculo numérico. Los tipos de datos primitivos de punto flotante (`float` o `double`) no son aptos para aplicaciones contables debido a los errores de redondeo binario inherentes a su representación de memoria.

Para garantizar que ningún centavo se pierda durante las conversiones de divisas, toda la lógica de negocio opera con `BigDecimal` utilizando la escala e integridad exigidas a nivel de base de datos (`precision = 19, scale = 4`).

### 🏦 Redondeo Bancario Estricto

Durante la operación de intercambio (Swap de MXN a USDC), el motor calcula la división de activos aplicando la constante `RoundingMode.HALF_UP` (redondeo simétrico al valor más cercano), asegurando la precisión contable de la plataforma.

```java theme={null}
// Lógica de conversión en PortafolioService.java
BigDecimal nuevoBalanceMxn = portafolio.getBalanceMxn().subtract(montoMxn);
portafolio.setBalanceMxn(nuevoBalanceMxn);

BigDecimal usdcComprados = montoMxn.divide(tipoCambio, 4, RoundingMode.HALF_UP);
BigDecimal nuevoBalanceUsdc = portafolio.getBalanceUsdc().add(usdcComprados);
portafolio.setBalanceUsdc(nuevoBalanceUsdc);
```
