Sanjyot Agureddy Ответов: 1

Избежать взаимоблокировки в SQL транзакции при использовании параллельно.по каждому элементу


I have a situation here, I need to insert a record in 10 tables and that's need to b atomic in nature hence I am using transaction, this need to be done for a collection of records and need to have better performance hence can't use sequential approach. However the SQL Transactions are causing deadlock in Parallel.ForEach and thus I need a different solution. Could anyone please advise how I can achieve this parallel processing with encountering any deadlocks??


Что я уже пробовал:

int[] itemListArr = GetAllItems();
        Parallel.ForEach(Partitioner.Create(0, itemListArr.Count(), 5),
            new ParallelOptions { MaxDegreeOfParallelism = 8 },
            (range) =>
            {
                for (int i = rangeFrom; i < rangeTo; i++)
                {
                    _database.BeginTransaction(connectionString);
                    try
                    {
                        foreach (var table in _template.Tables)
                        {

                            sqlCmd = string.Format(insertQuery, table.DestinationTable, strColumns, strColumnsValue);
                            _database.InsertWithMultiTransaction(sqlCmd);
                        }

                        _database.CommitTransaction();
                    }
                    catch (Exception ex)
                    {
                        _database.RollbackTransaction();
                    }

                }
            });

Richard Deeming

sqlCmd = string.Format(insertQuery, table.DestinationTable, strColumns, strColumnsValue);

Не делай этого так!

Ваш код почти наверняка уязвим для SQL-инъекция[^]. НИКОГДА используйте конкатенацию строк для построения SQL-запроса. ВСЕГДА используйте параметризованный запрос.

Все, что вы хотели знать о SQL-инъекции (но боялись спросить) | Трой Хант[^]
Как я могу объяснить SQL-инъекцию без технического жаргона? | Обмен Стеками Информационной Безопасности[^]
Шпаргалка по параметризации запросов | OWASP[^]

1 Ответов

Рейтинг:
12

Herman&lt;T&gt;.Instance

Ваша переменная _database по-видимому, определяется вне parallel.foreach Затем каждый поток использует один и тот же объект. Вы должны создать экземпляр _database в parallel.foreach Затем каждый поток имеет свой собственный вызов к базе данных.