powered by simpleCommunicator - 2.0.58     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Firebird выполнение запроса без ожидания результата
18 сообщений из 18, страница 1 из 1
Firebird выполнение запроса без ожидания результата
    #37976296
Pallaris
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Подскажите пожалуйста, будет ли выполняться код после приведенного ниже куска, не дожидаясь результатов от сервера? Или будет где-то стопориться, если сервер занят, например?
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
FbCommand sqlRequest = new FbCommand(query_, dbConn, dbTransact_);
                IAsyncResult res_ = null;
                try
                {
                    res_ = sqlRequest.BeginExecuteNonQuery(null,null);
                }
                catch (Exception ex)
                {
                    streamOutput.OutputLog("Error in SafeExecuteQueryAsync with query:", query_ + "\n" + ex.ToString());
                }
                finally
                {
                    sqlRequest.EndExecuteNonQuery(res_);
                }
...
Рейтинг: 0 / 0
Firebird выполнение запроса без ожидания результата
    #37976328
Фотография buser
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Здесь...
Код: c#
1.
sqlRequest.EndExecuteNonQuery(res_)

?
EndExecuteNonQuery
Примеры тут
...
Рейтинг: 0 / 0
Firebird выполнение запроса без ожидания результата
    #37976541
Pallaris
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
buserЗдесь...
Код: c#
1.
sqlRequest.EndExecuteNonQuery(res_)

?


Т.е. если у меня не задан callback в BeginExecute..., то не нужно вызывать EndExecute...?

И еще: можно ли вызывать BeginExecute... примерно раз в минуту для 50-60 коротеньких insert'ов, или так лучше не делать? Суть проблемы в следующем: есть один поток, который регулярно (раз в минуту) делает пачку insert'ов. Есть другой поток, который очень редко делает ресурсоемкий select (секунд на 10). И когда этот поток выполняется, то первый вешается на insert'е, пока select не закончится, вот я и пытаюсь этого избежать.
...
Рейтинг: 0 / 0
Firebird выполнение запроса без ожидания результата
    #37996380
Pallaris
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Подскажите плз, почему приложение со временем падает (тихо, без exception), если я выполняю запросы вот так:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
public override void SafeExecuteQueryAsync(string query_)
        {
            base.SafeExecuteQueryAsync(query_);
            if (dbConn != null && dbConn.State == ConnectionState.Open)
            {
                FbCommand sqlRequest = (FbCommand)BuildCommand(query_);
                IAsyncResult res_ = null;
                try
                {
                    
                    res_ = sqlRequest.BeginExecuteNonQuery(null, null);
                }
                catch (Exception ex)
                {
                    streamOutput.OutputLog("DB_", "Error in SafeExecuteQueryAsync with query:", query_ + "\n" + ex.ToString());
                }
                finally
                {

                }

            }
        }



а если вот так, то все нормально
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
public void SafeExecuteQuery(string query_)
        {
            if (TestConnection() == true)
            {
                if (dbConn != null && dbConn.State == ConnectionState.Open)
                {
                    try
                    {

                        DbCommand sqlRequest = BuildCommand(query_);
                        sqlRequest.ExecuteNonQuery();
                        operationsAmount_++;
                        if (operationsAmount_ >= commitAmount_)
                        {
                            CommitTransactionUpdate();
                        }
                    }
                    catch (Exception ex)
                    {
                        streamOutput.OutputLog("DB_", "Error in SafeExecuteQuery with query:", query_ + "\n" + ex.ToString());
                    }

                }
            }
        }



Методы вызываются каждую минуту для выполнения однотипных insert'ов (порядка 60-80 штук)
...
Рейтинг: 0 / 0
Firebird выполнение запроса без ожидания результата
    #37996392
Фотография buser
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот вперлось Вам держать шаренный dbConn. Есть же connection pool... Да и TestConnection() наверное что-то делает...? Да? Все пр-мы не решить запихивая в бекграунд дооолгие операции.
...
Рейтинг: 0 / 0
Firebird выполнение запроса без ожидания результата
    #37996394
Pallaris
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В TestConnection сидит такое

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
public bool TestConnection()
        {
            if (isConnected == true)
            {
                return true;
            }
            else
                if (allowReconnect_ == true && dbConn != null && (dbConn.State == System.Data.ConnectionState.Broken || dbConn.State == System.Data.ConnectionState.Closed))
                {
                    RestoreConnection();
                    return isConnected;
                }

            return false;
            
        }



С коннекшн pool не работал, сори. Поизучаю, но вроде с поддержанием одного соединения со старта проги проблем никогда не было.
...
Рейтинг: 0 / 0
Firebird выполнение запроса без ожидания результата
    #37996403
Фотография buser
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Connection strings for Firebird
Начните с простого - избавьтесь от глобальной dbConn. Открывайте соединения по необходимости и киляйте их сразу...
...
Рейтинг: 0 / 0
Firebird выполнение запроса без ожидания результата
    #37996412
Pallaris
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ок, спасибо за совет, займусь этим
...
Рейтинг: 0 / 0
Firebird выполнение запроса без ожидания результата
    #38001945
Pallaris
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
buserОткрывайте соединения по необходимости и киляйте их сразу...

Подскажите, не могу разобраться. Как быть с транзакциями? В приложении с одним постоянным соединением я создаю транзакцию, делаю commit после 40-ка insertoв, и далее по кругу. Мне не понятно, что будет с транзакцией, если я сделаю Connection.Close(), как велит pool? Для нее не страшно, если происходит close и коннект уходит в пул? Можно ли ей делать Commit, если коннект в пуле?

Т.е. если раньше у меня было
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
//гле-то при запуске программы
connection.Open();
.....
//далее в произвольном месте программы
trans_ = connection.BeginTransaction();
....
executeNonQuery();
...
executeNonQuery();
...
executeNonQuery();
...
executeNonQuery();
....
trans_.Commit();





то используя pool - надо так?
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
conn_ = new connection(connStr_);
conn_.Open();
trans_ = conn_.BeginTransaction();
executeNonQuery();
conn_.Close();
....
conn_ = new connection(connStr_);
conn_.Open();
executeNonQuery();
conn_.Close();
....
conn_ = new connection(connStr_);
conn_.Open();
executeNonQuery();
conn_.Close();
....
trans_.Commit();
...
Рейтинг: 0 / 0
Firebird выполнение запроса без ожидания результата
    #38002127
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Pallaris,

1 соединение на 1 UnitOfWork

Код: c#
1.
2.
3.
4.
5.
6.
7.
using (var connection = new FbConnection(...))
{
    var transaction = connection.BeginTransaction();
    // N раз вызываете свою команду
    ...
    transaction.Commit();
}
...
Рейтинг: 0 / 0
Firebird выполнение запроса без ожидания результата
    #38002162
Pallaris
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lelouch,

проблема в том, что команды не явно идут одна за одной, а вызываются из разных частей проги. Что-то типа

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
class MyApplication
{
  public void DoSomeWork()
 {
     foreach (object obj_ in objects_)
     {
           obj_.DoWork();
     }
  }
}

class MyObject
{
     public void DoWork()
     {
           .....
           myDb.SafeExecuteQuery(....);// выполнение inserta
     }
}



Т.е. надо бы по-хорошему в методе DoSomeWork перед циклом открыть соединение, запустить транзакцию, а в конце сделать коммит. Но я бы хотел всю рутину работы с БД инкапсулировать в классе myDb, чтобы не нужно было управлять соединениями и транзакциями вне этого класса. Что-то типа как сейчас у меня:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
251.
252.
253.
254.
255.
256.
257.
258.
259.
260.
261.
262.
263.
264.
265.
266.
267.
268.
269.
270.
271.
272.
273.
274.
275.
276.
277.
278.
279.
280.
281.
282.
283.
284.
285.
286.
287.
288.
289.
290.
291.
292.
293.
294.
295.
296.
297.
298.
299.
300.
301.
302.
303.
304.
305.
306.
307.
308.
309.
310.
311.
312.
313.
314.
315.
316.
317.
318.
319.
320.
321.
322.
323.
324.
325.
    public class DataBase
    {
        protected string dbFilePath;
        protected string dbServer="localhost";
        protected int writeFrequency;
        protected bool allowReconnect_ = true;
        protected int reconnectTimeOut_=20000;
        protected int commitAmount_ = 40;
        protected int operationsAmount_ = 0;

        protected DateTime lastReconnectTime_ = DateTime.MinValue;
        
        protected DbConnection dbConn;

        protected DbTransaction dbTransactUpdate_;

        public DbConnection connection
        {
            get { return dbConn; }
        }

        public string ServerName
        {
            set { dbServer = value; }
            get { return dbServer; }
        }

        public DbTransaction dbTransactUpdate
        {
            get
            {
                if (dbTransactUpdate_ == null)
                {
                    StartTransactionUpdate();
                }
                return dbTransactUpdate_; 
            }
        }



        public bool isConnected
        {
            get 
            {
                if (dbConn != null && dbConn.State == ConnectionState.Open)
                {
                    return true;
                }
                return false;
            }
        }

        public string filePath
        {
            get { return dbFilePath; }
            set { dbFilePath = value; }
        }

        public virtual DbCommand BuildCommand(string query_)
        {
            return null;
        }

        public virtual DbCommand BuildCommand(string query_,DbTransaction trans_)
        {
            return null;
        }

        public bool TestConnection()
        {
            if (isConnected == true)
            {
                return true;
            }
            else
                if (allowReconnect_ == true && dbConn != null && (dbConn.State == System.Data.ConnectionState.Broken || dbConn.State == System.Data.ConnectionState.Closed))
                {
                    RestoreConnection();
                    return isConnected;
                }

            return false;
            
        }

        public void RestoreConnection()
        {
            
                TimeSpan delta_ = DateTime.Now - lastReconnectTime_;
                if (delta_.TotalMilliseconds > reconnectTimeOut_)
                {
                    lastReconnectTime_ = DateTime.Now;
                    streamOutput.OutputLog("DB_", "Connection is lost to "+ServerName+":"+filePath+", restoring", "");
                    try
                    {
                        dbConn.Close();
                    }
                    catch (Exception ex)
                    {
                        streamOutput.OutputLog("DB_", "Error at connection closing in RestoreConnection()", ex.ToString());
                    }

                    try
                    {
                        dbConn.Open();
                    }
                    catch (Exception ex)
                    {
                        streamOutput.OutputLog("DB_", "Error at connection opening in RestoreConnection()", ex.ToString());
                    }
                }

        }


        public DataTable ReadDataToTable(string query_)
        {
            DataTable dt = null;
            if (TestConnection() == true)
            {
                
                DbDataReader sqlDataReader = null;
                CommitTransactionUpdate();

                try
                {

                    DbCommand sqlRequest = BuildCommand(query_);
                    sqlRequest.CommandType = CommandType.Text;
                    sqlDataReader = sqlRequest.ExecuteReader();
                    dt = new DataTable();
                    dt.Load(sqlDataReader);

                }
                catch (Exception ex)
                {
                    streamOutput.OutputLog("DB_", "Error in ReadData with query:", query_ + "\r\n" + ex.ToString());
                    return null;
                }
                finally
                {
                    if (sqlDataReader != null)
                    {
                        sqlDataReader.Close();
                    }
                }
                
            }
            return dt;
        }

        public virtual ArrayList ReadDataAsync(string query_)
        {
            return null;
        }

        public ArrayList ReadData(string query_)
        {
            ArrayList rows = null;
            if (TestConnection() == true)
            {
                DbDataReader sqlDataReader = null;
                CommitTransactionUpdate();

                try
                {

                    DbCommand sqlRequest = BuildCommand(query_);
                    sqlRequest.CommandType = CommandType.Text;
                    sqlDataReader = sqlRequest.ExecuteReader();
                    rows = new ArrayList();
                    while (sqlDataReader.Read())
                    {
                        object[] columns_ = new object[sqlDataReader.FieldCount];
                        sqlDataReader.GetValues(columns_);
                        rows.Add(columns_);
                    }

                }
                catch (Exception ex)
                {
                    streamOutput.OutputLog("DB_", "Error in ReadData with query:", query_ + "\r\n" + ex.ToString());
                    return null;
                }
                finally
                {
                    if (sqlDataReader != null)
                    {
                        sqlDataReader.Close();
                    }
                }
            }
            return rows;
        }

        public void StartTransactionUpdate()
        {
            if (TestConnection() == true)
            {
                
                if (dbTransactUpdate_ != null)
                {
                    CommitTransactionUpdate();
                }
                try
                {
                    dbTransactUpdate_ = dbConn.BeginTransaction();
                }
                catch (Exception exception)
                {
                    streamOutput.OutputLog("DB_", "Error in StartTransactionUpdate ", exception.ToString());
                    return;
                }
            }
        }

        

        public void CommitTransactionUpdate()
        {
            
                if (dbTransactUpdate_ != null)
                {

                    try
                    {
                        dbTransactUpdate_.Commit();
                        dbTransactUpdate_ = null;
                        operationsAmount_ = 0;
                    }
                    catch (Exception exception)
                    {
                        streamOutput.OutputLog("DB_", "Error in CommitTransactionUpdate ", exception.ToString());
                    }
                }
        }


        public int dbWriteFreq
        {
            get { return writeFrequency; }
            set { writeFrequency = value; }
        }

        public DataBase()
        {
            
            dbTransactUpdate_ = null;
            dbWriteFreq = 1000;
        }

        public virtual void Connect()
        {

        }

        public void Open()
        {
            if (dbConn != null)
            {
                try
                {
                    dbConn.Open();
                }
                catch (Exception exception)
                {
                    streamOutput.OutputLog("DB_", "Error in Open() ", exception.ToString());
                    return;
                }

            }
        }

        public void Close()
        {
            if (dbConn != null)
            {
                CommitTransactionUpdate();
                try
                {
                    dbConn.Close();
                }
                catch (Exception exception)
                {
                    streamOutput.OutputLog("DB_", "Error in Close() ", exception.ToString());
                    return;
                }
            }
        }

              

        public virtual void SafeExecuteQueryAsync(string query_)
        {

        }

        public void SafeExecuteQuery(string query_)
        {
            if (TestConnection() == true)
            {
                if (dbConn != null && dbConn.State == ConnectionState.Open)
                {
                    try
                    {

                        DbCommand sqlRequest = BuildCommand(query_,dbTransactUpdate);
                        sqlRequest.ExecuteNonQuery();
                        operationsAmount_++;
                        if (operationsAmount_ >= commitAmount_)
                        {
                            CommitTransactionUpdate();
                        }
                    }
                    catch (Exception ex)
                    {
                        streamOutput.OutputLog("DB_", "Error in SafeExecuteQuery with query:", query_ + "\n" + ex.ToString());
                    }

                }
            }
        }

    }
...
Рейтинг: 0 / 0
Firebird выполнение запроса без ожидания результата
    #38002525
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Pallaris,

модифицируйте свой класс (примерно так):

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
public class DataBase : IDisposable
{
 	//....

 	private bool _disposed;

	public void Dispose()
	{
		if (this._disposed) return;
		this.Close();
		this.dbConn.Dispose();
		GC.SuppressFinalize(this.dbConn);
		_disposed = true;
	}
}



И используйте его так же как писали выше:

Код: c#
1.
2.
3.
4.
5.
using (var connection = new DataBase(...))
{
    // N раз вызываете свою команду
    ...
}



Или я что то не так понял?
...
Рейтинг: 0 / 0
Firebird выполнение запроса без ожидания результата
    #38002541
pyroman69
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
уф, скока кода. Вроде выше написали, что надо открывать коннект, когда что-то надо выполнить.
Тут либо так:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
using (var connection = new FbConnection(...))
{
    using(var transaction = connection.BeginTransaction())
    {
       //insert    
       transaction.Commit();
    }
}


либо сделать буфер, куда будете закидывать запросы и например по 50 штук скидывать на выполнение:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
using (var connection = new FbConnection(...))
{
    using(var transaction = connection.BeginTransaction())
    {
       foreach(string insertQuery in insQueryList)
       {
           //insert    
       }       
       transaction.Commit();
    }
}


методы проверки соединения можно исключить при выполнении транзакции, просто добавьте try-catch.
...
Рейтинг: 0 / 0
Firebird выполнение запроса без ожидания результата
    #38002558
pyroman69
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
еще вот тут почитайте.
...
Рейтинг: 0 / 0
Firebird выполнение запроса без ожидания результата
    #38002624
Pallaris
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LelouchPallaris,

Код: c#
1.
2.
3.
4.
5.
using (var connection = new DataBase(...))
{
    // N раз вызываете свою команду
    ...
}



Или я что то не так понял?

Все-таки хотелось бы, чтоб экземпляр класса базы данных был один на всю программу. Который бы управлял транзакциями и соединением. И разработчику не нужно было париться над созданием соединений, запросов и объектов - ему дали объект базы данных, вот и пожалуйста, пользуйся им, передавай запросы.

Если б выполнялся запрос и делался сразу коммит, то все было бы просто. Вот скажите, может я зря парюсь по поводу транзакций, и большой разницы нет, что я сделаю 40+ запросов за секунду в одной транзакции, или же буду делать для каждого запроса begin()-commit()? Я вот думаю, второй вариант - отстой.
...
Рейтинг: 0 / 0
Firebird выполнение запроса без ожидания результата
    #38002640
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Pallaris,

У вас будет 1 экземпляр вашего класса на 1 UnitOfWork , в своем классе вы реализуете например логику управления транзакциями и т.д.

P.S. Я именно это и имел ввиду в последнем примере?
...
Рейтинг: 0 / 0
Firebird выполнение запроса без ожидания результата
    #38002641
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lelouch,

P.S. Я именно это и имел ввиду в последнем примере?
...
Рейтинг: 0 / 0
Firebird выполнение запроса без ожидания результата
    #38002650
Pallaris
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
pyroman69либо сделать буфер, куда будете закидывать запросы и например по 50 штук скидывать на выполнение:


Хм, как вариант, мб прокатит - я вызываю SafeExecuteQuery(stirng query_), где будет что-то типа

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
public void SafeExecuteQuery(string inQuery_)
{
  lock (queryList.SyncRoot)
  {
     queryList.Add(inQuery_);
     if (queryList.Count > maxQueryNum)
    {
        using (dbConn = Connect())
        {
              trans_ = dbConn.BeginTransaction();
              foreach(string query_ in queryList)
              {
                   // выполнение запроса
              }
              trans_.commit();
        }
       
     }
  queryList.Clear();
  }
}
...
Рейтинг: 0 / 0
18 сообщений из 18, страница 1 из 1
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Firebird выполнение запроса без ожидания результата
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]