You can check whether a transaction is already open by checking if cmd.Transaction
is null
.
Then wrap your code accordingly so if a transaction is already open, then the calling function owns that transaction and will commit it / roll it back appropriately.
<!-- language: lang-cs -->
//begin transaction unless one was already started
bool newTransaction = cmd.Transaction == null;
if (newTransaction) cmd.Transaction = cmd.Connection.BeginTransaction();
try {
// do Stuff Here
cmd.ExecuteNonQuery();
cmd.ExecuteNonQuery();
// commit if it's our to commit
if (newTransaction) cmd.Transaction.Commit();
} catch (SqlException ex) {
if (newTransaction && cmd.Transaction != null) cmd.Transaction.Rollback();
throw;
}
Then the parent function can pass in a command and optionally choose to begin it's own transactional block, or if not, one will be created and commited by the called function.