Que son las transacciones declarativas?

Varios conocen como se configuran las transacciones en Spring o frameworks similares, pero no muchos saben las ventajas por las cuales conviene utilizar este tipo específico de demarcación de transacciones. Voy a intentar contarles un poco acerca de que problemas soluciona este tipo de configuración, en contraposición a manejar las transacciones de forma programática.
Hace mucho, mucho tiempo, en una galaxia muy lejana, los programadores se encontraron frente al desafío de tener que lidiar con transacciones, según la definición wikipedista: "Una transacción es una interacción con una estructura de datos compleja, compuesta por varios procesos que se han de aplicar uno después del otro. La transacción debe realizarse de una sola vez y sin que la estructura a medio manipular pueda ser alcanzada por el resto del sistema hasta que se hayan finalizado todos sus procesos."

El enfoque programático

Para poder permitir que esa estructura a "medio manipular" pueda ser alcanzada por el resto del sistema, el primer aproach, fue el de utilizar dos sentencias para poder definir el inicio y el fin de la porción de código que lidiaba con un fragmento transaccional: es decir los famosos "begin" & "commit", con su infaltable contraparte "rollback".
Esas tres sentencias se usaron por mucho tiempo para manejar transacciones, y hoy en día mucha gente piensa que es la forma mediante la cual hay que lidiar con las mismas. En realidad no hay problemas en utilizar esto, pero a medida que los sistemas aumentan en complejidad, comienzan a notarse las falencias de este enfoque.
El primer gran problema es que claramente esto se trata de un "aspecto" del código que desarrollamos, y como tal, puede traer problemas si no es siempre tratado de similar manera. Por lo tanto es necesario implementarlo de forma separa de nuestro código para evitar olvidos o la posibilidad de codificarlo de forma diferente para cada funcionalidad.
Pero el verdadero gran problema es que el código tiene a complicarse mucho, si tenemos el caso de varias clases con diferentes métodos de lógica de negocio que se invocan entre sí. Cuando esto sucede, lo que normalmente se requiere, es que los métodos puedan "compartir" las transacciones entre sí, de tal manera de que solo uno de los métodos la inicie (el primero en ser invocado por la capa de presentación) y luego los otros utilicen este contexto transaccional ya creado. Esto normalmente se conoce como "propagación" de la transacción.
Si esto no se implementa de una forma declarativa, es decir "declarando" como cada método va a utilizar el aspecto de la transaccionalidad, es muy dificil de lograr un comportamiento similar, sin caer en el caso de tener que usar varios flags que se pasen como parámetro y cadenas de if que aumentan su complejidad a medida de que se van encadenando más y más métodos.

Declaremos

Utilizando Spring, como framework de inyección de dependencias, existen tres maneras de utilizar el enfoque declarativo, al momento de definir las transacciones de nuestro código:
  • Utilizando Proxys: Este es el enfoque más antiguo. Lo que hacemos es generar de forma dinámica un sustituto de nuestro Servicio, que lo que hace es agregar el manejo de transacciones, antes de cada método que respete un patrón de nombres que podemos especificar. Estos proxys se definen de una manera similar a la siguiente:
1:       <bean id="abstractTransactionManager" abstract="true">  
2:            <property name="transactionAttributes">  
3:                 <props>  
4:                      <prop key="save*">PROPAGATION_REQUIRED,ISOLATION_READ_COMMITTED</prop>  
5:                      <prop key="remove*">PROPAGATION_REQUIRED,ISOLATION_READ_COMMITTED</prop>  
6:                      <prop key="update*">PROPAGATION_REQUIRED,ISOLATION_READ_COMMITTED</prop>  
7:                      <prop key="ejecutar*">PROPAGATION_REQUIRED,ISOLATION_READ_COMMITTED</prop>  
8:                      <prop key="*">PROPAGATION_REQUIRED,readOnly,ISOLATION_READ_COMMITTED</prop>  
9:                 </props>  
10:            </property>  
11:       </bean>  
12:       <bean id="feriadosManager" parent="abstractTransactionManager" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">  
13:            <property name="target">  
14:                 <bean id="feriadosService" class="com.example.mysystem.service.FeriadosService">  
15:                      <property name="feriadosDAO" ref="feriadosDAO" />  
16:                 </bean>  
17:            </property>  
18:            <property name="transactionManager" ref="transactionManager_gateweb" />  
19:            <property name="proxyTargetClass" value="true" />  
20:       </bean>  

  • Utilizando Spring AOP: Como Spring tiene el "poder" de instanciar nuestras clases, el mecanismo de proxys se puede implementar de una forma aún más dinámica, definiendo la teoría de aspect-oriented-programming, con el sabor de Spring:
1:       <tx:advice id="commonTxAdvice" transaction-manager="transactionManager">  
2:            <tx:attributes>  
3:                 <tx:method name="save*" propagation="REQUIRED" />  
4:                 <tx:method name="remove*" propagation="REQUIRED" />  
5:                 <tx:method name="delete*" propagation="REQUIRED" />  
6:                 <tx:method name="update*" propagation="REQUIRED" />  
7:                 <tx:method name="execute*" propagation="REQUIRED" />  
8:                 <tx:method name="*" read-only="true" />  
9:            </tx:attributes>  
10:       </tx:advice>  
11:       <aop:config>  
12:            <!-- Pointcut -->  
13:            <aop:pointcut id="servicePointCut" expression="execution(* com.example.mysystem.service.impl.*.*(..))" />  
14:            <!-- Advisor -->  
15:            <aop:advisor advice-ref="commonTxAdvice" pointcut-ref="servicePointCut" />  
16:       </aop:config>  

De esta manera no es necesario recordar envolver a nuestros beans de servicio con un proxy transaccional, ya que se hace de manera automática de acuerdo al nombrado de los paquetes y de los nombres de los métodos. Esta manera es, según mi opinión, la mejor, ya que requiere mucho menos código y es más fácil de implementar.
  • Utilizando anotaciones: En este caso, utilizamos una anotación sobre el servicio que queremos que posea un comportamiento transaccional. La anotación utilizada es @Transactional:
1:  @Transactional  
2:  public class DefaultFooService implements FooService {  
3:    Foo getFoo(String fooName);  
4:    Foo getFoo(String fooName, String barName);  
5:    void insertFoo(Foo foo);  
6:    void updateFoo(Foo foo);  
7:  }  

Lo bueno de todo esto, es que los tres approachs se pueden usar side-by-side, sin ningún problema.
Igualmente hay que recordar, que dependiendo del enfoque, hay que tener en cuenta algunas configuraciones especiales. Lo mejor es, después de este artículo, pegarle una leída a la documentación oficial, que debería ser el primer lugar al cual referirse cuando se quiere conocer como se implementa algo utilizando un framework basado en una comunidad.
Antes que me olvide: no nos olvidemos que spring no es el primer framework y/o estándar en aplicar esta forma de manejar las transacciones, esto ya se viene implementando de una forma similar, desde los tiempos de los EJBs. Otros frameworks de DI, también tienen aproachs similares.
Nos vemos en el próximo post!

Construyendo proyectos .NET usando Maven

Los que me conocen saben que por lo general tiendo a usar Maven para todo, pero si lo hago, es porque estoy convencido de que está bueno tener un marco para ciertas tareas repetitivas, y despues de haber visto tantos enfoques, creo que lo que propone maven es bastante razonable, para prácticamente cualquier lenguaje.
Pero la idea de este post, no es hablar de lo que ofrece Maven, sino de describir cuales son las alternativas que existen hoy en día para poder utilizarlo en proyectos de la plataforma de Microsoft.
Cabe aclarar de que en mi carrera como desarrollador, comencé utilizando la plataforma .NET, antes que JAVA, cuando todavía estaba apareciendo, allá por el año 2000 (12 años ya pasaron, dios!). Luego la vida me llevó al mundo de la tacita de café, en el cual descubrí otras formas de construir aplicaciones; y luego de unos años me volví a enfrentar nuevamente a la tarea de arquitecturar y de trabajar con aplicativos de este sabor.
Acostumbrado como estaba a sistemas alineados con los lineamientos propuestos por Maven, debo confesar que pasé por varios estados de ánimo al ver que me faltaban ciertas características que ya las consideraba como básicas en todo proyecto de desarrollo, como ser el layout común de estructura de directorios, manejo de dependencias, de versionado, de releases, etc.
Entonces comencé a buscar diferentes maneras "hacer andar maven" con .NET. Ahorrando los detalles de la búsqueda, llegué a dos alternativas diferentes: NPANDAY y maven-dotnet-plugin.

NPANDAY

El primero es un proyecto al cual seguí por algunos años, comenzó como un tímido port de los plugins core de Maven pero evolucionó mucho a lo largo del tiempo, y actualmente se encuentra como proyecto incubadora en el cúmulo de Apache, lo cual no es poco.
El enfoque de este proyecto es acercar maven a los desarrolladores .NET, facilitando la vida a los que están acostumbrados a trabajar la mayor parte del tiempo, con la IDE N°1 de la plataforma: Visual Studio.
Tal es así que el proyecto está dividido en dos grandes partes: por un lado el gran conjunto de plugins que permiten hacer las tareas rutinarias (compilar, empaquetar, construir, liberar, etc.) del proyecto utilizando Maven y por otro lado un plugin para Visual Studio que permite realizar ciertas tareas (ciertas modificaciones a los archivos pom.xml, agregar dependencias, construir, etc.) desde adentro de la IDE.
Al comenzar a investigarlo, una de las cosas que no me gustó demasiado, es que el proyecto en sí, se aleja mucho de la filosofía Maven, en el sentido de que para comenzar tenemos que seguir una Guía de Instalación. Nada más alejado del espíritu Maven, de ser un software que se autoinstala en cierta manera, ya que todas  las partes que lo componen se van descargando a medida que se va utilizando. En las primeras etapas del proyecto, incluso, uno tenía que descargarse todo el repositorio completo para poder utilizarlo, y nuevas versiones de NPANDAY obligaban a tener nuevas versiones del repositorio! ... muy Microsoft :)  ... por suerte hoy en día todo está subido al repositorio mundial.
Otro de los problemas a los cuales me enfrenté, fue al hecho de que el plugin para Visual Studio, solo funciona si lo tenemos funcionando en idioma Ingles (a tenerlo en cuenta, ya que lamentablemente este tema todavía no está solucionado).
Con respecto a la documentación, que si bien existe y es bastante, me da la sensación de estar bastante desorganizada, uno no sabe por donde comenzar, sobre todo si ya tenemos un proyecto funcionando y lo queremos hacer andar con Maven, no hay una guía simple de como hacerlo. Tampoco si queremos empezar desde cero, sobre todo lo que es relacionado al manejo de dependencias. Una buena página para los que quieran comenzar, es la que muestra el listado de plugins existentes.
La verdad que luego de intentar utilizarlo llegué a varios problemas (como por ejemplo la falta de plugins de reporting, y un no muy buen esquema de directorios para el testing unitario) por lo que lamentablemente tuve que seguir buscando a ver si no existía alguna alternativa.

Maven-dotnet-plugin

Por suerte existe, este proyecto apareció tímidamente en la n-ésima búsqueda en google, y terminó sirviendo totalmente para lo que estaba necesitando. El enfoque es totalmente diferente: está pensado para las personas que ya conocen Maven, y que lo necesitan para poder construir proyectos en .NET
En este caso olvídense de plugins de visual studio y de grandes características. Es un simple proyecto que lo que intenta resolver es justamente, poder construir proyectos .NET usando Maven.
Ya desde el sitio oficial uno ya se siente a gusto con el layout utilizado, obviamente generado automáticamente por los plugins de Maven. Este proyecto si bien tiene algunas limitaciones (ej. no pude hacer andar el manejo de dependencias, lo cual lamentablemente es bastante malo), pose algunas características muy interesantes, como por ejemplo muchos plugins de reporting que funcionan de lo más bien con servidores de construcción como Jenkins (lo más interesante es que tenemos el reporte de DRY gracias al plugin CPD), una idea inicial de empaquetado de aplicaciones WEB, un muy buen enfoque de estructura de directorio e integración con Galio para el unit testing, todo esto a la Maven-way, es decir, se descarga cuando se usa.

Conclusión

Se que probablemente lo que esperaban es un análisis más detallado de las características de cada uno, pero les puedo dejar como conclusión, despues de haber utilizado las dos herramientas lo siguiente: NPANDAY se ve como un proyecto más grande, con más plugins, más líneas de código y más esfuerzo de fondo. Lamentablemente todavía tiene muchos problemas que lo hacen prácticamente inusable, y para colmo de males, el proyecto parece haberse detenido en la versión 1.4.0-SNAPSHOT, una pena realmente, ojalá en algún momento lo retomen y lo continúen. Con respecto a maven-dotnet-plugin, lo recomiendo, si bien es mucho más humilde y más simple, funciona, hace lo que promete y bien, y nos abre las puertas a tener proyectos similares, ordenados, liberables y construíbles contínuamente.
Nos vemos en el próximo post.

Eclipse Juno: Primeras impresiones

Todavía me estoy descargando la nueva versión de eclipse, pero ya tengo ganas de escribir un poco acerca de lo que pude advertir en las notas de lo nuevo que trae este release de una de las IDES más usadas para programar en lenguaje JAVA, y algunos otros como PHP, C++, etc.
Eclipse es un megaproyecto que, seguramente como a varios colegas, prácticamente me acompañó en toda mi vida de programador JAVA. Cuando me refiero a megaproyecto, me refiero a que ya tiene más de 20 años, lo cual no es poco en la vida de una IDE. También me refiero a que en realidad no es un único proyecto isolado, sino que es una organización incubadora de pequeñas joyas (como Mylyn, WTP, etc.) que viven dentro del ecosistema del mismo nombre.
Para los que no lo conocen (si es que hay alguien) o que no siguen los releases, hace un tiempo que se adoptó el formato de releases sincronizados anuales, con un nombre relacionado a lunas, dioses antiguos o científicos famosos. Esto fue necesario por la enorme cantidad de proyectos con versiones que dependen entre si (por ejemplo ahora fue un release de 72 proyectos simultáneos).

Nuevo y que valga la pena anotarlo

Leyendo un poco las famosas New and Noteworthy, lo primero que vemos es que despues de mucho tiempo, se optó por hacer un profundo rediseño del look & feel. La razón es adoptar un enfoque más moderno, y ocultar un poco de líneas, sobre todo en los elementos que no tienen el foco. Personalmente por lo que pude ver en las capturas, no me parece feo, pero me da la impresión de que tiene muchos espacios no aprovechados.
Relacionado a la usabilidad, pareciera que todos los elementos son un poco más flexibles. Ahora las vistas se pueden situar en el espacio de los editores, esto viene muy bien para vistas que muestran mucha información (como por ejemplo la Problems View). También se pueden disponer de forma dividida, para poder maximizar un editor, y al mismo tiempo tener una vista en la misma zona. Relacionado a esto, ahora los editores se pueden desatachar y convertirse en ventanas independientes.
Una cosa que me pareció curiosa, es que se puede seleccionar una intersección de vistas, y arrastrando se pueden dimensionar varias vistas al mismo tiempo.
Una de las cosas que por mucho tiempo diferenció a eclipse de otras IDEs, es que mantiene un "estado" de los archivos, interno e independiente de lo que ocurre por fuera de la IDE. Es decir que si uno tocaba un archivo con un editor externo, luego al trabajar con Eclipse, era necesario hacer un "refresh" (F5) sobre el mismo, para que tome los cambios. Ahora en esta nueva versión, existe un mecanismo habilitado por defecto, que lo que hace es hacer esa actualización de forma automática y en background.
Con respecto a lo que me pareció más llamativo, de lo nuevo que trae para los desarrolladores JAVA, tenemos resaltado de las llaves que engloban al código sobre el cual estamos parados (antes solo se hacía cuando estábamos parados sobre una de las llaves), posibilidad de asociar un editor a los archivos .class que no tienen código fuente asociado (antes era para todos los .class), detección de leaks cuando trabajamos con recursos y diferentes análisis para cuando trabajamos con las anotaciones @NonNull y @Nullable.
En fin, no son muchas cosas (igualmente acá estamos hablando solamente del core de la IDE, probablemente existan muchos más cambios en los proyectos satélites como WTP, etc.), pero vale la pena probarlo, ya que probablemente junto con estos new features, probablemente haya muchos bugfixes.
Terminé de bajarlo, asi que lo pruebo y les cuento!