lunes, octubre 25, 2004

La crisis de los huevos

Para una versión apocalíptica de una empresa, en este caso informática, no dejen de leer La crisis de los huevos por Fuckowski en Memorias de un programador. Una visión Orweliana altamente recomendable sobre si ver cuatro o cinco dedos en nuestras vidas.

(via Javi's Java)

lunes, octubre 11, 2004

Transacciones con AOP en Spring

AOP (Aspect Oriented Programming) nos ofrece una forma diferente de declarar servicios para muestra aplicación y sin entrar en detalle en todo el mundo AOP, podemos utilizar solamente un subconjunto de su funcionalidad para agregar transaccionalidad declarativa a los servicios que desarrollemos, utilizando method interception.

Spring AOP integra el soporte AOP en la infraestructura misma de Spring, permitiéndonos declarar la transaccionalidad de los servicios en el mismo XML de configuración de nuestros beans.

Típicamente, en Spring 1.1.1, definimos una plantilla para nuestras transacciones:

<bean id="daoTxProxyTemplate" abstract="true" 

class=
"org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager"><ref bean="transactionManager"/></property>
<property name="transactionAttributes">
<props>
<prop key="save*">PROPAGATION_REQUIRED</prop>
<prop key="remove*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
</bean>
en la cual está especificado el transactionManager que utilizaremos, y una serie de patterns de nombres de métodos, sobre los cuales definiremos que tipo de transacción es requerida para los métodos que se ajusten a ese pattern.

Luego solo queda comenzar a definir nuestros servicios, con la implementación como inner bean:

<bean id="itemManager" parent="daoTxProxyTemplate">

<property name="target">
<bean class="com.example.services.itemManagerImpl">
<property name="itemManagerDAO"><ref bean="itemManagerDAO"/></property>
</bean>
</property>
</bean>
Asi, ante cada llamada al método saveItem de la clase itemManagerImpl (definida en el bean itemManager), Spring creará una transacción (o reutilizará una existente) antes de la llamada, y hará el commit luego de ella.

Mas adelante podríamos seguir definiendo nuestro servicios, por ejemplo uno sin propiedades, y con los parámetros de propagación sobreescritos:

<bean id="miServicio" parent="daoTxProxyTemplate">

<property name="target">
<bean class="com.example.services.otroServicio"/>
</property>
<property name="transactionAttributes">
<props>
<prop key="load*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
</bean>
En cuanto a los tipos de propagación para las transacciones y su nivel de aislamiento, lo mas utilizado es simplemente PROPAGATION_REQUIRED, pero podemos optar por todos los definidos en la interfaz TransactionDefinition, utilizando el formato "PROPAGATION_NAME, ISOLATION_NAME, readOnly, timeout_NNNN, +Exception1, -Exception2", siendo PROPAGATION_NAME el único requerido.

En la definición de la plantilla de transacciones, también definimos una propiedad transactionManager. Este bean, puede tomar la forma de

<bean id="transactionManager" 

class=
"org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource"><ref bean="defaultDataSource"/></property>
</bean>
si trabajamos con JDBC directamente, o

<bean id="transactionManager" 

class=
"org.springframework.orm.hibernate.HibernateTransactionManager">
<property name="sessionFactory"><ref local="sessionFactory"/></property>
</bean>
si utilizamos Hibernate.

Queda para otro post como definir el sessionFactory de Hibernate y el dataSource (con pooling o sin el) necesarios.

domingo, octubre 03, 2004

Inexcusable excusa...

Leyendo mi dosis diria de blogs, di con esta anécdota en The Frustrated Programmer:

Al inicio del proyecto, un nuevo programador reportaba su progreso de creación de ficheros de configuración XML para Jasper. Estaba retrasado, y se le preguntó el por qué. Quedamos un poco atontados con sus razones:
"Bueno, XML es muy verboso. Cada vez que comienzas una etiqueta, tienes que terminarla."
A lo que llegamos para justificarnos :)