Supongamos que alguien (aparte de mí), escribe el siguiente código y compila en un ensamblado:¿Puedo obtener una referencia a una transacción pendiente desde un objeto SqlConnection?
using (SqlConnection conn = new SqlConnection(connString))
{
conn.Open();
using (var transaction = conn.BeginTransaction())
{
/* Update something in the database */
/* Then call any registered OnUpdate handlers */
InvokeOnUpdate(conn);
transaction.Commit();
}
}
La llamada a InvokeOnUpdate (IDbConnection conn) llama a un controlador de eventos que pueda implementar y registrar. Por lo tanto, en este controlador tendré una referencia al objeto IDbConnection, pero no tendré una referencia a la transacción pendiente. ¿Hay alguna manera en que pueda obtener la transacción? En mi manejador OnUpdate Quiero ejecutar algo similar a lo siguiente:
private void MyOnUpdateHandler(IDbConnection conn)
{
var cmd = conn.CreateCommand();
cmd.CommandText = someSQLString;
cmd.CommandType = CommandType.Text;
cmd.ExecuteNonQuery();
}
Sin embargo, la llamada a cmd.ExecuteNonQuery() lanza un InvalidOperationException quejándose de que
"ExecuteNonQuery requiere el comando tener una transacción cuando la conexión asignada al comando es en una transacción local pendiente. La propiedad Transaction del comando no se ha inicializado ".
¿Puedo de alguna manera enlistar mi cmd de SqlCommand con la transacción pendiente? ¿Puedo recuperar una referencia a la transacción pendiente desde el objeto IDbConnection (me gustaría usar el reflejo si es necesario)?
Puedo estar equivocado, pero me parece que su sugerencia requiere que pueda hacer que la biblioteca de terceros que estoy utilizando crea una instancia de MyConnection en lugar de una simple SqlConnection. Desafortunadamente, no tengo el código fuente y no admite la inyección de dependencia en ninguna forma. – Rune
No estoy seguro de lo que quiere decir. En su caso, su clase "MyConnection" tomaría SqlConnection, OleConnection o lo que tiene como argumento. No se necesita inyección. Eche un vistazo a cómo funciona el "Patrón de diseño de delegación", como aquí: http://en.wikipedia.org/wiki/Delegation_pattern – Denis
Veo lo que quiere decir. Tu caso es difícil porque estás dejando que un tercero cree tu conexión, en mi caso estoy creando muchas conexiones, pero son globales en mi aplicación, así que estoy perdiendo constantemente la pista de quién está abriendo qué transacciones y me gustaría mantener las transacciones con mi conexión. En su caso, supongo que después de que su conexión creada por un tercero se transfiera a MyConnection, se hará un seguimiento de las transacciones. Debe averiguar si el tercero creó una transacción antes de obtener un contacto, por lo que no tendría más remedio que utilizar el reflejo para encontrar la transacción inicial. – Denis