2008-10-27 8 views
12

Tengo una aplicación web en el trabajo que es similar a un sistema de trabajo de tickets. Algunos usuarios ingresan nuevos problemas. Otros trabajadores eligen y resuelven problemas. Todos los datos se mantienen en el servidor MS SQL 2005.Cómo evitar que los usuarios trabajen en la misma fila

Los usuarios que trabajan para resolver problemas van a una página donde pueden ver problemas abiertos. Debido a que hasta veinte personas pueden mirar esta página al mismo tiempo, un problema potencial que tuve que abordar fue qué sucede si alguien selecciona un problema que alguien más eligió justo después de cargar la página.

Para resolver esto, hice dos cosas. En primer lugar, la vista de cuadrícula que muestra los problemas para seleccionar utiliza un temporizador AJAX para actualizar cada segundo. Una vez que se ha seleccionado un problema, desaparece un segundo más tarde como máximo. En caso de que seleccionen uno dentro de este segundo, recibirán un mensaje pidiéndoles que elijan otro.

El problema es que la parte AJAX de esto está enviando demasiadas actualizaciones (esto es lo que asumo) y está afectando el rendimiento de la página y la base de datos. Además, las actualizaciones no se realizan cada segundo. Creo que el temporizador no es confiable cuando se trabaja para activar procedimientos almacenados.

Tiene que haber una mejor manera, pero parece que no puedo encontrar una. ¿Alguien tiene experiencia con una situación como esta o tiene sugerencias para evitar que varios usuarios seleccionen el mismo registro para mantener? Realmente no quiero deshabilitar la parte AJAX por completo porque siento que el mensaje solo haría que la aplicación sea frustrante de usar.

Gracias,

Respuesta

3

Dos cosas pueden ayudar a mitigar su problema.

En primer lugar, es necesaria la notificación de selección posterior de que se ha llevado el caso, independientemente de su marco de tiempo de actualización de AJAX.Incluso consultar cada segundo no significa que dos personas no pueden hacer clic en el mismo caso en lo que perciben que es al mismo tiempo. En tales casos, uno de los usuarios debe ser notificado de que su selección no es válida, aunque parezca válida cuando se seleccione. Esta notificación no necesita ser elaborada; mantener un tono ligero y útil puede mejorar la percepción del usuario incluso a la luz de la decepción. Y si ya identifica al usuario que seleccionó ese registro, eso no solo ayudará a los usuarios a coordinar en el futuro, sino que también desviará la atención de su programa hacia el usuario que se encargó del caso. (De hecho, la administración puede como dar a sus usuarios la colisión de vez en cuando, ya que los motivará para seleccionar los casos más rápido)

En segundo lugar, un pequeño pellizco a cómo mostrar sus casos puede reducir las colisiones de selección. Agregar un elemento aleatorio para mostrar el orden y/o filtrar cada dos casos en la pantalla ayudará a los usuarios a seleccionar diferentes casos de forma natural. El reconocimiento de patrones humanos y la selección de tareas no son realmente aleatorios, por lo que pequeños cambios en la presentación pueden ser grandes cambios en el comportamiento de selección. Las reducciones en la probabilidad de colisión mantienen raras las notificaciones de colisión (y por lo tanto, son menos frustrantes para los usuarios). Esto es aún mejor si sus usuarios pueden separarse en clasificaciones que pueden ayudar a determinar el orden/filtro de caso útil.

Bien, una tercera cosa que te ayudará con el tiempo es si mantienes un registro de cuándo ocurren las colisiones (con metadatos útiles sobre la colisión — como quién estuvo involucrado y el momento de la selección). Armado con datos sólidos de colisión, puede encontrar lo que funciona y lo que no funciona. Con el tiempo, puede perfeccionar su aplicación a sus casos de uso reales, así como identificar problemas potenciales de manera temprana. Nada tranquiliza más a tus usuarios que estar a la cabeza de un problema (y poder explicar tus planes para resolverlo) incluso antes de que se den cuenta de que existe.

Con estos patrones mitigantes, es probable que encuentre que puede reducir de forma segura el tiempo de consulta de su AJAX sin afectar la experiencia del usuario. Y con un registro útil, tendrá la seguridad de que cualquier ajuste que ponga en marcha realmente está funcionando (o no —, que tal vez sea aún más útil saber).

+0

+1 para la asignación al azar, ¡exactamente lo que iba a sugerir! –

+1

La orden aleatoria no funcionará. Los tickets se priorizan por vencimiento del nivel de servicio. –

+1

¿Cuál es la base de la caducidad del nivel de servicio? ¿Es eso una determinación basada en el tiempo? Dependiendo de su número, puede agruparlos al minuto más cercano (o quince minutos) y que sean "lo suficientemente buenos". De todos modos, sé que pedir una excepción a la priorización y ser políticamente problemático, pero si * puedes *, puede que valga la pena. –

2

¿Usted ha intentado aumentar el tiempo entre actualizaciones. Esperaría que una vez cada 30 segundos fuera suficiente. 40 solicitudes/minuto es mucho menos carga que 1200/minuto. Es posible que sus usuarios ni siquiera noten la diferencia.

Si lo hacen, qué hay de proporcionar un botón de actualización en la página para que los usuarios puedan actualizar manualmente la lista antes de seleccionar un elemento para evitar el mensaje molesto si lo desean.

+0

He llegado a pensar que AJAX utilizado de esta manera no es una buena solución en absoluto, ya sea cada segundo o cada 30 segundos. La actualización es una buena idea. No he pensado en eso. Un pequeño enlace sobre la vista de cuadrícula funcionaría muy bien. Aún así, pierde parte de su usabilidad. –

+0

Normalmente utilizo la actualización para notificar a los usuarios cuando se ha agregado información nueva cuando no han navegado por un tiempo. Aunque, mi frecuencia de actualización es más como de 5 minutos. – tvanfosson

+0

Corrígeme si me he perdido algo, pero esto parece recomendar la solución de un problema de concurrencia con una llamada 'sleep()' en lugar de usar un bloqueo. No resolverá el problema de ediciones simultáneas, solo lo enmascara. – asveikau

2

Si es posible, limite el sistema para que solo obtengan el siguiente problema abierto fuera de la cola de trabajo en lugar de que puedan elegir entre todos los problemas abiertos.

Si eso no es posible, supongo que podría verificar la elección de un problema para ver si todavía está disponible. Si no está disponible, hágalo desaparecer después de que el usuario haga clic en él. De esta forma, solo está solicitando cuando hacen clic en algo, en lugar de realizar un sondeo constante de los datos.

+0

Desafortunadamente, debido a la naturaleza del trabajo, limitarse al siguiente en cola no es una opción. Me gusta la idea de que desaparezca cuando el usuario hace clic en ella si ya se ha seleccionado, pero me preocupa que solo frustrará a los usuarios. –

+0

Creo que la posible frustración del usuario es una preocupación muy válida. Definitivamente querrías hacer un prototipo para la aceptación del usuario si sigues esta ruta. Creo que definitivamente estás en una situación difícil aquí con concurrencia vs usabilidad. –

+0

Gracias por los comentarios. Ya sabes, cuando comencé a trabajar con AJAX pensé: "Finalmente, esto permitirá que los usuarios trabajen sincronizados con los datos". No estoy exactamente decepcionado, pero definitivamente me olvidé de manera selectiva del rendimiento. –

4

Ponga un campo de marca de tiempo de bloqueo en la fila en la base de datos. Escriba un proceso almacenado que devuelva verdadero o falso si la marca de tiempo de expiración es anterior a un tiempo específico. Configure sus sesiones en su aplicación web para que expiren al mismo tiempo, uno o dos minutos. Cuando un usuario selecciona una fila, accede al proceso almacenado que ayuda a la aplicación a decidir si debe permitir que el usuario lo modifique.

esperanza que tiene sentido ....

+0

No tengo mucha experiencia con su método, pero creo que lo entiendo. ¿Intentarían los usuarios potencialmente modificar los registros que aún se hayan seleccionado? Lo que realmente me gustaría hacer, si es posible, es evitar que se preocupen por la selección de registros no disponibles. –

+0

Bueno, ¿cómo puedes ocultarlos si no ha habido una devolución de datos al servidor? –

+0

ajax utilizando un jquery baby – craigmoliver

3

hice algo similar en el que una vez que un usuario abre un billete (fila) se le asigna ese boleto a ese usuario y establecer un valor en ese disco, al igual que a FK usuario particular, por lo que si alguien más intentara abrir ese ticket (fila), les avisaría que ya se le ha asignado a otra persona.

+0

Eso es realmente una parte de lo que estamos haciendo ahora. Cambiamos el código de estado del problema para indicar que se está manteniendo. Actualizamos continuamente una marca de tiempo que mantiene el registro en este estado siempre que se actualice. Esto solo todavía tendría usuarios seleccionando registros que no pueden trabajar. –

1

Me falta ver el problema, especialmente después de que usted mencionó que ya está marcando entradas como en progreso/manteniéndose y tiene una marca de tiempo/versión del artículo.

¿No es suficiente el siguiente:

  1. usuario navega por los billetes y ve una lista de entradas disponibles es decir, esto excluye a los que están en el PP como en progreso. Si desea que los usuarios también vean los tickets en progreso, indíquelos claramente en el estado del ticket y desactive la opción para tomarlos.
  2. El usuario marca un ticket como en curso de forma explícita o implícita abriendo el ticket (depende de la experiencia del usuario/cómo se presenta a los usuarios).
  3. usuario se mueve de forma explícita el boleto a un estatus diferente, es decir completado, no válida, a la espera para la retroalimentación, etc.

Cuando se recuperan los elementos a 1, se incluye una marca de tiempo/versión. Cuando ocurre 2, usa un enfoque de concurrencia optimista para asegurarse de que si 2 personas intentan actualizar el ticket al mismo tiempo, solo el primero tendrá éxito.

Lo que sucederá es que para la segunda persona, la actualización ... donde ... timestamp = @timestamp no encontrará ningún registro para actualizar y usted informará que el ticket ya se tomó.

Si lo desea, puede agregar lo anterior para actualizar la interfaz de usuario a medida que se toman los tickets.Esto podría ser simplemente haciendo una actualización completa de la página actual de tickets después de x tiempo (tal vez alertando/solicitando al usuario), o incluso recuperando una lista de boletos cambiados para la página de boletos que se muestran con ajax. Aún tiene los pasos anteriores en su lugar, ya que esta modificación es solo una conveniencia para los usuarios.

+0

Todo lo que describió está sucediendo ahora. El problema es que la actualización de gridview con AJAX es ineficiente. Si configuro el temporizador de actualización en un intervalo más largo, los usuarios comienzan a seleccionar el mismo registro. La concurrencia optimista mantiene los datos bajo control, pero desperdicia el tiempo del usuario. Debe imaginar una lista de 300 elementos ordenados por prioridad y hasta 20 usuarios seleccionando el más alto. –

Cuestiones relacionadas