sábado, 7 de septiembre de 2013

Plugins: Transacciones en Pre/Post operations

Después de un tiempo de inactividad en mi blog (aunque no en otras áreas), vuelvo con mcuhas ganas con todo lo nuevo que se viene.
Hoy quiero explicar un poco como funcionan los plugins en los Pre y Post operations.
Al comenzar la ejecución de un plugin en estos pasos, CRM crea una transacción, que provoca que a veces no podamos hacer algunas de las cosas que necesitamos.
En primer lugar al registro que lanza el plugin, se le provoca un bloqueo en la base de datos de SQL Server, que puede provocar que hacer acciones sobre el mismo no se puedan realizar y nos genere unos errores inesperados.
Por otro lado, se inicia una transacción en donde se van guardando los cambios realizados en el registro que lanza el plugin y que además hace un rollback de cualquier otro registro que se cree o modifique.
A continuación pongo un código de ejemplo:
   1: IPluginExecutionContext context =
   2:                 (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
   3:  
   4:             IOrganizationServiceFactory factory =
   5:                 (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
   6:             IOrganizationService service = factory.CreateOrganizationService(context.UserId);
   7:              
   8:  
   9:             ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
  10:  
  11:             tracingService.Trace("Creacion de contacto");
  12:  
  13:             Entity acc = new Entity("account");
  14:             acc.Attributes.Add("accountid",context.PrimaryEntityId);
  15:             acc.Attributes.Add("accountnumber","1232333");
  16:             service.Update(acc);
  17:  
  18:  
  19:             Entity cont = new Entity("contact");
  20:             cont.Attributes.Add("lastname", "Raschkovan");
  21:             cont.Attributes.Add("firstname", "Demian Adolfo");
  22:  
  23:             Guid id=service.Create(cont);
  24:  
  25:             throw new InvalidPluginExecutionException("La cuenta ha sido creada con el id " + id.ToString() + ", pero se quita por estar en transaccion.");

 
Este plugin esta pensado para lanzarse al hacer un “Update” del nombre de la Cuenta. Lo que hace es primero actualizar el numero de cuenta y luego crear un contacto.

En caso de que se produzca un error como el que estoy forzando allí, todo lo que se haya creado o actualizado durante la ejecución del Plugin, es deshecho con un Rollback.

Si lo ejecuto lo que ocurre es lo siguiente:
image

Si comento la última línea, quedan correcto el update de la cuenta y se crea el contacto.

Esto esta muy bien, pero…¿si necesito por ejemplo lanzar una excepción para hacer una validación y además crear un registro en CRM, como lo hago?

Para encontrar una solución, primero hay que entender como guarda CRM esta transacción. Como se ve en el código, yo utilizo el “service” que me da el CRM con el contexto de ejecución del plugin. Todo lo que yo haga con ese contexto, quedará bajo la transacción y por lo tanto desaparecerán con el Rollback.

Entonces, si quiero realizar una operación fuera de la transacción y así evitar un posible Rollback, la solución pasaría por crearnos una nueva llamada a los web services de CRM, por fuera de la conexión que nos da el contexto de CRM. Esto se puede hacer o bien añadiendo una llamada directa a los web services de CRM pasándole las credenciales usuario y password, o a través de algún web service intermedio.

No hay comentarios:

Publicar un comentario