Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

367
Vistas
¿Cómo anidar transacciones en EF Core 6?

Ya estoy usando transacciones dentro de mis funciones de repositorio en algunos casos porque a veces necesito insertar datos en dos tablas a la vez y quiero que toda la operación falle si falla una de las inserciones.

Ahora me encontré con una situación en la que tenía que envolver llamadas a múltiples repositorios/funciones en otra transacción, pero cuando una de esas funciones ya usa una transacción internamente, obtendré el error The connection is already in a transaction and cannot participate in another transaction . No quiero eliminar la transacción de la función de repositorio porque esto significaría que tengo que saber para qué funciones de repositorio se requiere una transacción que luego tendría que implementar en la capa de servicio. Por otro lado, parece que no puedo usar funciones de repositorio en una transacción cuando ya usan una transacción internamente. Aquí hay un ejemplo de dónde estoy enfrentando este problema:

 // Reverse engineered classes public partial class TblProject { public TblProject() { TblProjectStepSequences = new HashSet<TblProjectStepSequence>(); } public int ProjectId { get; set; } public virtual ICollection<TblProjectStepSequence> TblProjectStepSequences { get; set; } } public partial class TblProjectTranslation { public int ProjectId { get; set; } public string Language { get; set; } public string ProjectName { get; set; } public virtual TblProject Project { get; set; } } public partial class TblProjectStepSequence { public int SequenceId { get; set; } public int ProjectId { get; set; } public int StepId { get; set; } public int SequencePosition { get; set; } public virtual TblStep Step { get; set; } public virtual TblProject Project { get; set; } } // Creating a project in the ProjectRepository public async Task<int> CreateProjectAsync(TblProject project, ...) { using (var transaction = this.Context.Database.BeginTransaction()) { await this.Context.TblProjects.AddAsync(project); await this.Context.SaveChangesAsync(); // Insert translations... (project Id is required for this) await this.Context.SaveChangesAsync(); transaction.Commit(); return entity.ProjectId; } } // Creating the steps for a project in the StepRepository public async Task<IEnumerable<int>> CreateProjectStepsAsync(int projectId, IEnumerable<TblProjectStepSequence> steps) { await this.Context.TblProjectStepSequences.AddRangeAsync(steps); await this.Context.SaveChangesAsync(); return steps.Select(step => { return step.SequenceId; } ); } // Creating a project with its steps in the service layer public async Task<int> CreateProjectWithStepsAsync(TblProject project, IEnumerable<TblProjectStepSequence> steps) { // This is basically a wrapper around Database.BeginTransaction() and IDbContextTransaction using (Transaction transaction = await transactionService.BeginTransactionAsync()) { int projectId = await projectRepository.CreateProjectAsync(project); await stepRepository.CreateProjectStepsAsync(projectId, steps); return projectId; } }

¿Hay alguna manera de anidar varias transacciones una dentro de otra sin saber en las transacciones internas que podría haber una transacción externa? Sé que puede que no sea posible anidar esas transacciones desde una perspectiva técnica, pero todavía necesito una solución que use la transacción interna del repositorio o la externa (si existe), así que no hay forma de que pueda accidentalmente Olvídese de usar una transacción para las funciones de repositorio que lo requieran.

over 4 years ago · Santiago Trujillo
1 Respuestas
Responde la pregunta

0

Puede verificar la propiedad CurrentTransaction y hacer algo como esto:

 var transaction = Database.CurrentTransaction ?? Database.BeginTransaction()

Si ya hay una transacción, utilícela; de lo contrario, inicie una nueva...

Editar: se eliminó el bloque Uso, ver comentarios. Sin embargo, se necesita más lógica para Confirmar/Revertir la transacción...

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda