|

Tuesday May 11, 2004
DAO... Esta traducción inicio como una simple lectura de el articulo, pero no se por que razón
termino siendo una traducción, así que no esperen que sea perfecta, una que otra cosa mal
traducida o interpretada, algunas faltas de ortografia y la peor no supe como interpretar
"Transaction demarcation" o mas bien no le haye sentido a mi traduccion en ese momento y despues
me dio flojera cambiar todo, asi que la deje tal cual, y una que otra cosa mas que omito,
en fin espero sirva....
Esta traducción esta basada en el siguiente articulo:
Advanced DAO programming
Learn techniques for building better DAOs
Sean C. Sullivan (dao-article@seansullivan.com)
Software Engineer
7 October 2003
http://www-106.ibm.com/developerworks/java/library/j-dao/
Tecnicas para desarrollar mejores DAO's
El patrón de diseño J2EE DAO se usa para separar las operaciones de bajo-nivel de acceso a
datos(low-level data access), de las operaciones de alto nivel de la lógica del negocio
(high-level business logic). Implementar el patron DAO implica mas que solo escribir el
código del acceso a datos. En este articulo, el desarrollador Sean C. Sullivan aborda tres
aspectos frecuentemente descuidados de la programación DAO: "Transaction demarcation",
manejo de errores y logging.
En este articulo, pondré en practica las estrategias y técnicas para construir mejores
clases DAO's. Especificamente sobre logging, manejo de excepciones y "Transaction demarcation".
Aprenderas como incorporarlos en tus clases DAO. Este articulo asume que estas
familiarizado con el API JDBC, SQL, y programación de bases de datos relacionales.
Comenzare con un repaso al patron de diseño DAO y los objetos de acceso a datos.
Fundamentos DAO
El patron DAO es una de los patrones de diseño estandard de J2EE. Los desarrolladores usan
este patron para separar las operaciones de acceso a datos de las operaciones de la logica
del negocio. Una implementación DAO típica contiene:
Una clase DAO factory
Una interfase DAO
Una clase concreta que implemente la interfase DAO (1)
Objetos de transferencia de Datos (algunas veces llamados value objets)
(1) contiene la lógica para accesar los datos desde una fuente especifica.
En las secciones siguientes aprenderás técnicas para diseñar e implementar objetos de acceso
a datos. Ve recursos(2) para mayor detalle acerca de el patron de diseño DAO.
Definición de una transacción
(Transaction demarcation)
Una cosa importante sobre los DAO's es recordar que son objetos transaccionales.
Cada operación hecha por un DAO, como crear, actualizar o barrar datos esta asociada a una
transacción. Por lo que el concepto "transaction demarcation" es muy importante.
"Transaction demarcation" es la forma en como se define el limite de la transacción.
La especificación J2EE dispone dos modelos para "Transaction demarcation": programmatic y
declarative.
Declarative transaction demarcationEl programador declara los atributos de una transacción usando un EJB deployment descriptor.
El entorno en tiempo de ejecución (el EJB container) usa los atributos para automáticamente
manejar las transacciones.
Programmatic transaction demarcation
El programador es responsable de codificar la lógica de las transacciones.
La aplicación controla la transacción por medio de un API.
Este ultimo es el que se considera para este articulo.
Consideraciones en el diseñoCuando se diseñe un DAO de este tipo, comience haciéndose las siguiente preguntas
Como iniciara la transacción?
Como terminara la transacción?
Que objeto sera responsable de iniciar la transacción?
Que objeto sera responsable de terminar la transacción?
Debería este DAO ser el responsable de iniciar y terminar transacciones?
Necesitaría la aplicación accesar datos por medio de múltiples DAO's?
Puede una transacción involucrar un DAO o varios DAO's?
Puede un DAO invocar métodos en otro DAO?
El responder estas preguntas ayudara a seleccionar que método de "transaction demarcation" es
la mejor para tus DAO's. Hay dos métodos principales de "transaction demarcation" en DAO's.
Uno hace al DAO responsable por la "transaction demarcation"; el otro desplaza la "transaction
demarcation" a el objeto que esta llamando al método DAO. Si seleccionas la primera forma
pondrías el código de la "transaction demarcation" dentro de la clase DAO, si escoges la
segunda opción el código de la "transaction demarcation" debe estar fuera de la clase DAO.
El siguiente ejemplo muestra un DAO con dos operaciones hacia datos: crear y actualizar.
public void createWarehouseProfile(WHProfile profile);
public void updateWarehouseStatus(WHIdentifier id, StatusInfo status);
Este ejemplo muestra una transacción sencilla. El código de la "transaction demarcation" esta
fuera de la clase DAO. Observe como en este ejemplo se combinan múltiples operaciones DAO
dentro de la transacción.
tx.begin(); // start the transaction
dao.createWarehouseProfile(profile);
dao.updateWarehouseStatus(id1, status1);
dao.updateWarehouseStatus(id2, status2);
tx.commit(); // end the transaction
Este método o forma de "transaction demarcation" es muy valiosa para aplicaciones que necesitan
acceder varios DAO's desde una sola transacción.
Tu puedes implementar "transaction demarcation" usando JDBC API o Java Transaction API (JTA).
La primera es mas fácil, pero JTA tiene mayor flexibilidad.
"Transaction demarcation" con JDBC.Las transacciones JDBC son contralodas usando el objeto Connection. La interfase JDBC Connection
(java.sql.Connection) proporciona dos modos de transacción:
auto-commit y manual commit. java.sql.Connection ofrece los siguiente métodos para controlar
transacciones:
public void setAutoCommit(boolean)
public boolean getAutoCommit()
public void commit()
public void rollback()
Ejemplo de "Transaction demarcation" con JDBC API.
import java.sql.*;
import javax.sql.*;
// ...
DataSource ds = obtainDataSource();
Connection conn = ds.getConnection();
conn.setAutoCommit(false);
// ...
pstmt = conn.prepareStatement("UPDATE MOVIES ...");
pstmt.setString(1, "The Great Escape");
pstmt.executeUpdate();
// ...
conn.commit();
// ...
Con JDBC "Transaction demarcation", puedes combinar varias sentencias de SQL en una transacción.
Uno de los inconvenientes de las transacciones JDBC es que el (scope) de la transacción
esta limitado a una conexión a base de datos. Una transacción JDBC no puede emplear varias bases
de datos.
Ahora toca el turno a JTA, y como no es tan conocido como JDBC, se iniciara con una repaso.
Repaso JTA.
Java Transaction API (JTA) y su hermano Java Transaction Service (JTS), proporcionan servicios de
transacciones distribuidas para la plataforma J2EE. Una transacción distribuida involucra un
manejador de transacciones y uno o mas manejadores de recursos. Un manejador de recursos es
cualquier tipo de "datastore" con persistencia. El manejador de transacciones es responsable de
coordinar la comunicación entre todas las transacciones involucradas.
Las transacciones JTA son mas poderosas que las JDBC. Mientras que una transacción JDBC esta
limitada a una conexión a base de datos, una transacción JTA puede tener varias de estas.
Cualquiera de los siguiente componentes de la plataforma Java puede usarse en una transacción JTA:
JDBC connections
JDO PersistenceManager objects
JMS queues
JMS topics
Enterprise JavaBeans
Un adaptador de recurso que cumpla con la especificación de la arquitectura de Conectores J2EE.
"Transaction demarcation" con JTA.Para usar "Transaction demarcation" con JTA, la aplicación invoca métodos de la interfase
javax.transaction.UserTransaction.
El siguiente ejemplo muestra un típico lookup JNDI para el objeto UserTransaction.
import javax.transaction.*;
import javax.naming.*;
// ...
InitialContext ctx = new InitialContext();
Object txObj = ctx.lookup("java:comp/UserTransaction");
UserTransaction utx = (UserTransaction) txObj;
Después de que la aplicación ha hecho referencia a el objeto UserTransaction este puede iniciar
la transacción como se muestra a continuación:
utx.begin();
// ...
DataSource ds = obtainXADataSource();
Connection conn = ds.getConnection();
pstmt = conn.prepareStatement("UPDATE MOVIES ...");
pstmt.setString(1, "Spinal Tap");
pstmt.executeUpdate();
// ...
utx.commit();
// ...
Cuando la aplicación invoca a commit(), el manejador de transacciones usa un protocolo commit de
dos faces para finalizar la transacción.
Métodos JTA para control de transacciones.La interfase javax.transaction.UserTransaction ofrece los siguiente métodos de control de
transacciones:
public void begin()
public void commit()
public void rollback()
public int getStatus()
public void setRollbackOnly()
public void setTransactionTimeout(int)
Al comenzar una transacción la aplicación llama a begin(). Para finalizar una transacción la aplicación
llama a cualquiera de estos métodos commit() o rollback().
Usando JTA y JDBC.Los desarrolladores a menudo usan JDBC para operaciones de datos a bajo nivel en las clases DAO.
Si tu planeas utilizar transacciones con JTA, necesitarías un driver JDBC que implemente las
interfaces javax.sql.XADataSource, javax.sql.XAConnection, y javax.sql.XAResource.
Un driver que implemente estas interfases es capaz de emplear transacciones JTA. Un objeto
XADataSource es una fabrica de objetos XAConnection. XAConnections son conexiones JDBC
que se utilizan en transacciones JTA.
Podrias necesitar configurar el XADataSource usando las herramientas administrativas de tu
servidor de aplicaciones. Consulta la documentación de tu servidor de aplicaciones y la
documentación del driver JDBC para instrucciones mas especificas.
Las aplicaciones J2EE buscan datasource usando JNDI. Una vez que la aplicación dispone
de una referencia a el objeto datasource, esta puede llamar a javax.sql.DataSource.getConnection()
para obtener una conexión a base de datos.
Una conexión XA es diferente de una conexión no-XA o_O. Siempre recuerde que una conexión
XA es participe de una transacción JTA. Esto quiere decir que una conexión XA no soporta
JDBC auto-commit. Ademas la aplicación no debe invocar a java.sql.Connection.commit()
o java.sql.Connection.rollback() en una conexión XA. En vez de eso la aplicación podría usar
UserTransaction.begin(), UserTransaction.commit(), y UserTransaction.rollback().
Eligiendo la mejor estrategia.Hemos visto como definir transacciones con JDBC y JTA. Cada metodo tiene desventajas y tu
necesitas decidir cual es la mas apropiada para tu aplicación.
En varios proyectos recientes nuestro equipo ha desarrollado clases DAO usando el API JDBC para
"Transaction demarcation". Estas clases DAO pueden ser resumidas de la siguiente manera:
El código de la "Transaction demarcation" esta dentro de las clases DAO.
Las clases DAO usan el API JDBC para "Transaction demarcation".
El (caller) no tiene forma de demarcar la transacción.
El (scope) de la transacción esta limitado a una conexión JDBC.
Las transacciones JDBC no siempre son adecuadas para aplicaciones complejas. Si tus transacciones
abarcan multiples DAO's o multiples base de datos la siguiente estrategia podría ser mas
adecuada:
Las transacciones son demarcadas con JTA.
El código de esa demarcación esta fuera de las clases DAO.
El (caller) es responsable de la demarcación de la transacción.
El DAO participa en una transacción global.
JDBC es atractivo debido a su simplicidad; JTA ofrece gran flexibilidad. La especificación que
tu elijas dependera específicamente de las necesidades de tu aplicación.
Logging y DAO's.Una clase DAO bien implementada debería usar logging para capturar detalles hacerca de
como se comporto durante su ejecución. Tu podrías elegir crear logs para las excepciones,
información de la configuración, estatus de la conexión, JDBC driver metadata o los
parámetros de un query. Los logs son útiles en todas las fases del desarrollo. Yo a menudo
examino los logs de la aplicación durante el desarrollo, durante las pruebas y en producción.
En esta sección, presentare un código de ejemplo que muestra como incorporar Jakarta Commons Logging
dentro de un DAO. Antes de hacer eso, demos un vistazo a algunas casas básicas.
Eligiendo una libreria de logging.Muchos desarrolladores usan una forma primitiva de logging: interparlamentarios y
System.err.println. Las sentencias Println son rápidas y convenientes, pero ellas no ofrecen el
poder de un sistema de logging.
En esta tabla se muestra una lista de librerías de logging para la plataforma Java.
| Libreria de logging |
Open source? |
URL |
| java.util.logging |
No |
http://java.sun.com/j2se/ |
| Jakarta Log4j |
Si |
http://jakarta.apache.org/log4j/ |
| Jakarta Commons Logging |
Si |
http://jakarta.apache.org/commons/logging.html |
java.util.logging es el API estandard para la plataforma J2SE. La mayoría de los desarrolladores
deberían de aceptar, sin embargo, Jakarta Log4j ofrece gran funcionalidad y mas flexibilidad.
Una de las ventajas de Log4J sobre java.util.logging es que soporta las plataformas J2SE 1.3
y J2SE 1.4.
Jakarta Commons Logging puede ser usada en conjunto con java.util.logging o Jakarta Log4j.
Commons Logging es un logging abstraction layer que separa tu aplicación de la implementación
del logging. Con Commons Logging, alternar la implementación del logging cambiando un archivo
de configuración. Commons Logging es usado en Jakarta Struts 1.1 y Jakarta HttpClient 2.0.
Un ejemplo de logging.En este ejemplo se muestra como usar Jakarta Commons Logging en una clase DAO.
import org.apache.commons.logging.*;
class DocumentDAOImpl implements DocumentDAO
{
static private final Log log = LogFactory.getLog(DocumentDAOImpl.class);
public void deleteDocument(String id)
{
// ...
log.debug("deleting document: " + id);
// ...
try
{
// ... data operations ...
}
catch (SomeException ex)
{
log.error("Unable to delete document", ex);
// ... handle the exception ...
}
}
}
El Logging es una parte esencial de cualquier tarea critica en una aplicación. Si tu
encuentras una anomalia en un DAO, los logs a menudo proporcionan la mejor información
para entender que es lo que esta mal. Incorporar logging en tus DAO's asegura que estas
equipado para depurar y arreglar errores.
Manejo de Excepciones en DAO's.Hemos visto una definición de transacción y logging y ahora tienes una profundo conocimiento
de como aplicarlos en tus DAO's. Nuestro tercer y ultimo punto es el manejo de excepciones.
Siguiendo unas simples directivas del manejo de excepciones podrías hacer a tus DAO's fáciles
de usar, mas robustos y facilitar su mantenimiento.
Cuando apliques el patron DAO, ten en cuenta las siguiente preguntas:
Los métodos en la interfase publica de los DAO's lanzan checked exceptions?
Si si, que checked exceptions deberían lanzar?
Como deberían de ser manejadas las excepciones dentro de la implementación de la clase DAO.
En el proceso de trabajar con el patron DAO, nuestro equipo fijo ciertas
directivas para el manejo de excepciones. siguiendo esas directivas mejoro mucho nuestros DAO's
Los métodos DAO deberían lanzar excepciones con significado.
Los métodos DAO no deberían lanzar java.lang.Exception. java.lang.Exception es demasiado genérica.
No transmite ninguna información acerca de la raíz del problema.
Los métodos DAO no deberían lanzar java.sql.SQLException. SQLException es una excepción JDBC
de bajo nivel. Un DAO debería esforzarse para encapsular el JDBC antes que mostrar el JDBC al
resto de la aplicación.
Los métodos en la interfase DAO debería lanzar checked exceptions solo si la clase que la
llamo puede anticipar el manejo de la excepción. Si la clase que llama no es capaz de manejar
la excepción considera lanzar una unchecked (run-time) exception.
Si tu código de acceso a datos cacha una excepción, que no la ignore. Los DAO's que ignoran
una excepción cachada son problemáticos.
Use chained exceptions para cambiar excepciones de bajo nivel a excepciones de alto nivel.
Considere fijar un estandard para las clases de excepciones DAO.
El framework Spring tiene un excelente conjunto de clases de excepciones DAO predefinidas
Ve recursos(2) para mayor detalle acerca de las excepciones y técnicas de manejo de excepciones.
Ejemplo de implementación: MovieDAO.MovieDAO es un DAO que muestra todos las técnicas vistas en este articulo: "Transaction demarcation",
logging, y manejo de excepciones. Encontraras el fuente de MovieDAO en la sección de recursos(2)
El código se divide en tres paquetes:
daoexamples.exception
daoexamples.movie
daoexamples.moviedemo
Esta implementación del patron DAO consiste el las siguiente interfaces y clases:
daoexamples.movie.MovieDAOFactory
daoexamples.movie.MovieDAO
daoexamples.movie.MovieDAOImpl
daoexamples.movie.MovieDAOImplJTA
daoexamples.movie.Movie
daoexamples.movie.MovieImpl
daoexamples.movie.MovieNotFoundException
daoexamples.movie.MovieUtil
La interfase MovieDAO define la operación de datos de los DAO's.
La interfase tiene cinco métodos:
public Movie findMovieById(String id)
public java.util.Collection findMoviesByYear(String year)
public void deleteMovie(String id)
public Movie createMovie(String rating, String year, String, title)
public void updateMovie(String id, String rating, String year, String title)
El paquete daoexamples.movie contiene dos implementaciones de la interfase MovieDAO.
Cada implementación usa una estrategia diferente de "Transaction demarcation",
como se muestra en la siguiente tabla:
| |
MovieDAOImpl |
MovieDAOImplJTA |
| Implements the MovieDAO interface? |
Si |
Si |
| Obtains DataSource via JNDI? |
Si |
Si |
| Obtains java.sql.Connection objects from a DataSource? |
Si |
Si |
| DAO demarcates transactions internally? |
Si |
No |
| Uses JDBC transactions? |
Si |
No |
| Uses an XA DataSource? |
No |
Si |
| Participates in JTA transactions? |
No |
Si |
Aplicaión demo MovieDAO.La aplicación demo es una clase servlet llamada daoexamples.moviedemo.DemoServlet. DemoServlet
usa ambos DAO's de Movie para consultar y actualizar datos de una pelicula en una tabla.
Este servlet muestra como combinar JTA-aware MovieDAO y código JMS en una transacción.
transacciones utx = MovieUtil.getUserTransaction();
utx.begin();
batman = dao.createMovie("R",
"2008",
"Batman Reloaded");
publisher = new MessagePublisher();
publisher.publishTextMessage("I'll be back");
dao.updateMovie(topgun.getId(),
"PG-13",
topgun.getReleaseYear(),
topgun.getTitle());
dao.deleteMovie(legallyblonde.getId());
utx.commit();
Para correr la aplicación demo, configura un datasource XA y un datasource no-XA en tu servidor
de aplicaciones. Despues haz deploy a el archivo daoexamples.ear. La aplicación puede correr
en cualquier servidor de aplicaciones que soporte J2EE 1.3. Ve recursos(2) para obtener el
archivo EAR y el código fuente.
Conclusion.En este articulo se mostró como la implementación del patron DAO implica mas que solo
escribir código de bajo nivel para acceso a datos. Tu puedes empezar a desarrollar mejores
DAO's, eligiendo la definición de transacción(Transaction demarcation) que sea apropiada
para tu aplicación, incorporando logging a tus clases DAO y siguiendo unas simples directivas
para el manejo de excepciones.
Recursos
Baja el codigo fuente de la clase MovieDAO: http://daoexamples.sourceforge.net/
(2) http://www-106.ibm.com/developerworks/java/library/j-dao/#resources
(2004-05-11 11:06:41.0)
Permalink

Monday May 03, 2004
Mi primera vez....
Bueno creo que este es mi primer post en un weblog y que mejor que en el mio :P
Gracias ha javahispano por brindarme este espacio, que espero sea util para alguien mas.
Antes que nada le contare un poco parte de mi vida, osea como es que llegue hasta aqui.
Actualmente trabajo en una consultoria, como analista de sistemas (aveces como programador, documentador, tester y servicio tecnico a pc's :) ), que por diversos problemas economicos del pais(Mexico) y otros tantos por no tener una buena organizacion (a mi parecer) casi llegamos a desaparer, pero actualmente estamos nuevamente de regreso, ya tenemos varios proyectos y aunque todavia no estamos al 100% ya se ve una mejora bastante.
Ya hace algunos años que empece con esto de la programacion y bueno para ser sicero, es una de mis pasiones, me encanta programar, y bueno ya entrados en historias he aqui un poco de la mia...
Todo empezo hace mas de 8 años, y de hecho es una historia curiosa pues en esos tiempos ya estaba desesperado por trabajar, en cualquier cosa, y un dia me llama una amiga para preguntarme sobre una direccion, pues tenia una entrevista de trabajo y no sabia donde quedaba, y ya platicando de que era y todo me dice, por que no llevas tus papeles haber que pasa, y bueno queriendo y no, pues era una entrevista para ella, y con la presion de encontrar trabajo pues que me voy con ella con todo y curriculum, y bueno para no hacer larga la historia yo me quede en el trabajo y ella no :( . Asi fue como consegui mi primer trabajo y que mejor que era de mi area, entre a trabajar a una consultoria, en un proyecto para un banco y programando con cobol (mi lenguage favorito en ese tiempo), ha todavia recuerdo esos dias con nostalgia, pero la verdad por mucho que me haya gustado ese lenguaje, que por cierto pocos son a los que les gusta almenos que yo conozca, la verdad ha java no lo cambio, por un buen rato, unque para ser siceros, me costo un buen entender esto de la programacion oo, de hecho tome 2 veces el curso de "the java programming lenguage sl-275" y no fue hasta que no tome el curso "migrating to oo programming with java technology sl/210" que le entendi y eso a medias, ya despues con el curso "objet-oriented application analysis and design for java (UML) oo-226" ya estuvo un poco mas claro, aunque todavia tenia mis lagunas, y es que migrar de programacion estructurada a programacion oo es bastante dificil o almenos para mi lo fue, y la verdad tuve suerte pues la empresa en la que entre se certifico con SUN como educational center y los cursos no nos costaban nada, a parte de que en ese entonces era prioridad de la empresa que todos supieramos Java, ya con estos antecedentes y despues de andar vagando por diversos lenguajes y una que otra cosa en Java, la verdad nada de importancia creo yo, no fue hasta mi segundo trabajo(el actual) que entro de lleno a trabajar con Java, concretamente java y jsp.
(2004-05-03 13:30:14.0)
Permalink
|