I have created a singleton class for holding the Firebird database connection and I'm executing queries (see below), which worked like a charm, until I had to add to one of the applications some timers to set up & check some data regularly.
Now very often I get error saying that "Parallel transactions are not supported". I can't get it, because I got closing of the connection in finally block.
I already spent few very long evenings on searching the web and trying to figure out how to approach, but it seems I need support.
Here is the main part of my fBird
class:
public sealed class fBird {
private FbConnection FbConn = new FbConnection(connectionString);
static fBird m_oInstance = null;
static readonly object m_oPadLock = new object();
public static fBird Instance {
get {
lock (m_oPadLock) {
if (m_oInstance == null) {
m_oInstance = new fBird();
}
return m_oInstance;
}
}
}
//Data query:
public DataTable qSelect(string query){
if(!getState().Equals("Open")) FbConn.Open();
using (FbTransaction transaction = FbConn.BeginTransaction()) {
try{
FbCommand cmd = new FbCommand(query, FbConn, transaction);
FbDataAdapter adpt = new FbDataAdapter(cmd);
DataTable dt = new DataTable();
adpt.Fill(dt);
transaction.Commit();
return dt;
} catch (Exception ex){
transaction.Rollback();
throw new Exception("DataQuery: " + ex.Message);
} finally {
FbConn.Close();
}
}
}
//NonQuery query:
public int NonQuery(string query){
if(!getState().Equals("Open")) FbConn.Open();
using (FbTransaction transaction = FbConn.BeginTransaction()) {
try{
FbCommand cmd = new FbCommand(query, FbConn, transaction);
int i = cmd.ExecuteNonQuery();
transaction.Commit();
return i;
} catch (Exception ex){
transaction.Rollback();
throw new Exception("NonQuery: " + ex.Message);
} finally {
FbConn.Close();
}
}
}
}
Here is how I use the class:
DataTable dt = fBird.Instance.qSelect("SELECT * FROM USERS");
int i = fBird.Instance.NonQuery("DELETE FROM TABLE");
Here is how I use timers:
public partial class MainForm : Form {
private System.Timers.Timer aTimer;
...
void setTimers() {
aTimer = new System.Timers.Timer(1500));
aTimer.Elapsed += OnTimedEvent;
aTimer.AutoReset = true;
aTimer.Enabled = true;
}
void OnTimedEvent(Object source, ElapsedEventArgs e) {
try{
//different changes to & reads from database
} catch(Exception ex) {
MessageBox.Show("OnTimedEvent: " + ex.Message);
}
}
}
What I have found out is that for some reason there is more than one connection to Firebird made (singleton shouldn't allow that, right?). I can see it in Windows Performance Monitor on Network tab. As a testing I do very different operations, open different windows & screens in application, also save some changes. At random I got error (parallel transactions) and new connection is created and than for some time (like 30-40 clicks) all works fine.
It just drives me crazy. I hope someone of you will be able to help me. I have feeling that I do something really wrong here, but I just can't find it. Let me know if you need any more information.