сделать транзакцию при записи в базу данных

Есть метод который принимает List и этот метод записывает эти данные в базу данных, я хочу чтоб все это происходило транзакционно, и если где-нибудь произойдет ошибка, чтобы произошел Rollback.

 public async Task Insert(List<Details> prob)
 {
            using (OracleConnection conn = new OracleConnection(con))
            {
                //OracleTransaction trans = conn.BeginTransaction();

                foreach (var item in prob)
                {
                    using (OracleCommand cmd = new OracleCommand("INF.PROBLEM.INSERT_P", conn))
                    {
                        cmd.CommandType = CommandType.StoredProcedure;

                        cmd.Parameters.Add("P", OracleDbType.VarChar).Value = item.P;
                        cmd.Parameters.Add("PH", OracleDbType.VarChar).Value = item.PH;
                        cmd.Parameters.Add("PL", OracleDbType.Number).Value = Int32.Parse(item.PL);

                        await cmd.Connection.OpenAsync();

                        await cmd.ExecuteNonQueryAsync();
                    }
                }
                //trans.Rollback();
            }
   }

Ответы (1 шт):

Автор решения: Konst

команду заранее определяем и выполняем с новыми значениями из цикла (откат для всех значений из цикла):

using (OracleConnection conn = new OracleConnection(con))
{
    await conn.OpenAsync();

    using (OracleCommand cmd = new OracleCommand("INF.PROBLEM.INSERT_P", conn))
    {
        cmd.CommandType = CommandType.StoredProcedure;          

        OracleParameter param1  = new OracleParameter("P", OracleDbType.VarChar);
        OracleParameter param2  = new OracleParameter("PH", OracleDbType.VarChar);
        OracleParameter param3  = new OracleParameter("PL", OracleDbType.Number);
        cmd.Parameters.Add(param1);
        cmd.Parameters.Add(param2);
        cmd.Parameters.Add(param3);
                  
          using (OracleTransaction transaction = conn.BeginTransaction(IsolationLevel.ReadCommitted)) 
          {
                cmd.Transaction = transaction;                      
                try 
                {   
                    foreach (var item in prob)
                    {               
                        param1.Value = item.P;
                        param2.Value = item.PH;
                        param3.Value = Int32.Parse(item.PL);
                        
                        await cmd.ExecuteNonQueryAsync();
                    }   
                    // Finally, commit all the inserts
                    transaction.Commit();
                }
                catch (DataException e) {
                    transaction.Rollback();
                }                         
          }
    }
}
→ Ссылка