Nuestra web de Java EE aplicación realiza operaciones de base de datos utilizando iBatis (ORM). La base de datos flujo de operación es la siguiente

Flujo : JSP —>Acción—>ServiceIMpl—>DaoImpl—->Llamar a consulta de actualización thru’ IBatis

Nota: La Acción, Servicio & clases DAO se crea una instancia de usar Spring 2.5 a la Dependencia de la técnica de Inyección. Utilizamos Struts2.

Problema: 2 usuarios simultáneos de búsqueda para el mismo registro y actualizaciones de Usuario1 Attribute1 mientras Usuario2 actualizaciones Attribute2. Usuario1 en primer lugar hace clic en «Guardar» y, a continuación, Usuario2 hace clic en guardar (se siguen el uno al otro con una diferencia de pocos segundos). Cuando vemos los datos en la base de datos, sólo el Usuario1 la actualización está presente. La Auditoría de las columnas también muestran sólo la del Usuario1 actualización. El Usuario2 la actualización en Attribute2 no se hace , en el sametime, no se producen Excepciones.

Tratamos de usar la transacción begin y commit de la transacción en iBatis rodean a la llamada de la consulta de actualización definida en el sqlmap xml. El mismo problema persiste. También hemos probado la eliminación de los comandos de transacción, sin embargo, el problema persiste.

Debemos hacer algo especial o diferente para manejar la concurrencia durante las actualizaciones ? No Orm como iBatis manejar por sí mismos ?

Información adicional: investigación Adicional reveló la siguiente información.

Cuando Usuario1 & Usuario2 clics en un registro completo de datos se recuperan para su visualización.

Ahora cuando ambos Usuario1 & Usuario2 cambios que pocos atributos y haga clic en guardar (simultáneamente), decir en primer lugar, Usuario1 la que se actualizan los datos y, a continuación, mientras que Usuario2 de datos se está actualizando, la ha actualizado los datos de User1 es la sobre-escrito & perdido.

What approach is usually followed in such screens to handle such scenarios ?

  • Esta no es realmente una struts2 pregunta. No sé iBatis, pero es extraño no es la excepción es lanzada, aumentar el nivel de registro, si es posible. Averiguar qué esquema de bloqueo está siendo utilizado, considere la posibilidad de bloqueo optimista.
  • he actualizado a la pregunta con algunas actualizaciones más..
InformationsquelleAutor yathirigan | 2012-09-27

2 Comentarios

  1. 9

    Su problema no es con las transacciones, es que antes de modificar algo que usted debe estar seguro de que nadie ha modificado desde la última lectura.

    De aplicaciones web debe utilizar el bloqueo optimista. Básicamente, usted tiene una «versión» de los campos de la tabla, que tiene un valor inicial en insert (típicamente 1), y se incrementa con cada update. El procedimiento es el siguiente:

    1. Leer los datos de la tabla, incluyendo el campo de la versión

    2. Enviar los datos del lado del cliente, incluyendo el campo de la versión

    3. Recibir datos modificados desde el cliente, incluyendo el campo de la versión sin cambios

    4. Actualización de la tabla de y el incremento de la versión, pero sólo si la versión de campo en la fila es el mismo que el original recibido del cliente. Que es, donde se había

      update
      ... 
      where id = :id_from_client

      ahora usted debe hacer

      update 
      ..., 
      version = version + 1 
      where 
      id = :id_from_client and 
      version = :version_from_client
    5. Obtener el número de filas actualizadas (generalmente, usted puede obtener esta información a la derecha de la operación de actualización de su marco de persistencia). Si el número de filas actualizadas es 1, la operación de éxito. Si el número de filas actualizadas es 0, se debe señalar una concurrencia de error.

    Un ejemplo:

    1. Usuario1 obtener los datos, con la versión = 17

    2. Usuario2 obtener los datos, con la versión = 17

    3. Usuario1 atómico (atomicidad viene de ser una única instrucción SQL):

      • Comprobar si la versión = 17
      • Actualizaciones de los datos
      • Conjuntos de versión 18

    4. Usuario2 atómicamente:

      • Comprobar si la versión = 17
      • Como versión fue realmente 18, señales de una concurrencia de error y aborta la operación, informando al usuario de que la operación no se pudo completar debido a que alguien la modificación de los mismos datos.

    Más actual de la persistencia de los marcos tienen soporte para esta fuera de la caja y en su mayoría de forma automática (ver JPA @Versión de anotación, por ejemplo). iBatis parece que no tenemos, pero como está muy cerca de SQL, usted no debería tener muchos problemas para implementar a ti mismo. Ver esta entrada de blog para algunos detalles sobre el bloqueo optimista con iBatis.

    Con este esquema, que no se pierdan las actualizaciones, el único problema es que en algunos casos específicos molestar a los usuarios un montón: imagina que pasar 5 minutos a completar algún formulario sólo para decir al final que su operación no se pudo completar y necesita volver a intentar desde el principio!! En estos pocos casos, usted debe poner en práctica algo más sofisticado en la parte superior de bloqueo optimista. Me gustaría utilizar algún tipo de recurso remoto de arrendamiento (links??):

    1. El cliente solicita un arrendamiento de los datos al servidor.

    2. Si los datos ya está arrendado a otro cliente, señal de una concurrencia de error.

    3. Demás conceder el contrato de arrendamiento para el cliente para una cantidad finita de tiempo.

    4. Antes del vencimiento del arrendamiento, el servidor concede al cliente un acceso exclusivo a los datos. El cliente también puede solicitar una renovación de contrato (a través de AJAX, por ejemplo). El servidor puede aceptar o denegar la renovación. (Tiempos de concesión y renovación de las políticas debe ser decidido por el servidor, dependiendo del caso de uso específico de que se trate).

    5. El vencimiento del contrato (esto se puede hacer con una tarea programada en el servidor, por ejemplo). Cuando caduca la concesión, los datos deben ser considerados «desbloqueado», y el servidor debe negar el acceso del cliente a menos que el cliente se concede un nuevo contrato de arrendamiento.

    De esta manera, los usuarios podrán estar informados de que alguien es modificar los mismos datos incluso antes de que comiencen lo largo de la operación estaban tratando de completar.

    • +1 El sistema de arriendo de que usted describe es una aplicación de bloqueo pesimista en el nivel de servicio. Este es uno de los más fáciles de sistemas a implementar (y buena). Una más desafiante del sistema sería dejar el bloqueo optimista, si se produce una colisión, el usuario se presenta con datos suficientes para resolver la situación si es necesario. La interfaz de usuario puede obtener un poco más complicado. Otro sistema (implementados por las JPA a través de oyentes) es el registro de cada cliente interesado y aplicar la propiedad en el registro, el giro es la implementación de un «tirón», característica que le permite robar la propiedad.
    • Tienes razón, es sólo que diciendo: «el bloqueo pesimista» implica el bloqueo indefinido y el nivel de DB a muchas personas (incluido yo mismo). Yo prefiero llamar «contrato de arrendamiento» a los planteamientos similares a lo que he descrito, y dejar «el bloqueo pesimista» para LOCK TABLE..., SELECT ... FOR UPDATE y ese tipo de cosas.
    • gracias por el tiempo para proporcionar una respuesta detallada. Al leer acerca de los Optimistas & bloqueo Pesimista conceptos, yo también estaba mirando a su alrededor si iBatis ORM será compatible con cualquier tales características out-of-the-box, pero parece que no, a diferencia de JPA ORM.
    • he empezado a buscar opciones para incluir el bloqueo Optimista característica como una re-utilizable característica el uso de AOPs en la Primavera o el uso de AspectJ .. cualquier punteros/direcciones son bienvenidos….
  2. 1

    Ibatis no realizar el bloqueo .Viendo la suya escenario optimista de bloqueo puede resolver el problema.Para lograr el bloqueo optimista usted puede tener opciones.
    1.El uso de marco de apoyo para la gestión de transacciones como org.springframework.jdbc.origen de datos.
    DataSourceTransactionManager
    .Ellos proporcionan la propagación de comportamiento y nivel de aislamiento.Pero,el origen de datos que está utilizando debe admitir la propagación de nivel y de nivel de aislamiento.Spring proporciona siguiente nivel de aislamiento.
    .ISOLATION_DEFAULT
    .ISOLATION_READ_UNCOMMITTED
    .ISOLATION_READ_COMMITTED
    .ISOLATION_REPEATABLE_READ
    .ISOLATION_SERIALIZABLE.
    2.A continuación, puede proporcionar el tuyo aplicación de bloqueo optimista.

Dejar respuesta

Please enter your comment!
Please enter your name here