FAQ

[Struts-user] How do I prevent two calls concurrently?

Givler, Eric
Jan 15, 2008 at 3:03 pm
I have a Struts application where a user enters an account id#
and a pin to enter the application. The user will already be
authenticated via an LDAP server prior to accessing my application, so
the remote user name is there, as well as role information. After the
user clicks [login], I fire a method that calls a stored proc to see if
the combination of their account/pin is valid in the database. I pass
their username as well. If the user has entered an invalid account# 5
times, they are to be locked out of just my application. When I issue
the check to see if the account# is invalid, I have to create a row to
track these invalid login attempts per this account. The problem is the
user double clicks [login] and can get two calls to the service method
to execute simultaneously. They both don't see a row, so they both do
an INSERT. One of the inserts fails due to a PK on the username.

How would I prevent this from occurring? My code that invokes
this service call is like:

public ActionForward login( ... )
{
// retrieve acct/pin from struts form

// I'd like to track/log user interaction with service, so
service
// has username as property
String user = request.getRemoteUser();
LoginService svc = new LoginService( user );

// acct object has other information about call (# bad
attempts, success flag, failure msg, last access date, etc.
Account acct = svc.login( user, acct, pin );
if (acct.isLoginSuccessful() {
// forward to next page
else
// return to input page, storing failure msg with #
attempts into ActionMessage

I'd appreciate any suggestions. I tried to simulate how this
might happen by creating multiple threads of the service, but then I
realized that each instance I created would still allow me to run the
login method concurrently, even if it was synchronized. I can imagine
that there are probably other areas in the application that might allow
multiple inserts of the EXACT same data if this double click occurs if
the PK is based on a sequence.

[Questions]
1. Is it simply a matter of making my service an instance
variable of this action and making the login method synchronized? 2.
Are there situations where I would not want there to be a single service
instance? Could it cause a bottleneck?

Every day I realize how little I know. Thanks for any/all
tips/pointers.

Eric
reply

Search Discussions

4 responses

  • Manos Batsis at Jan 15, 2008 at 3:12 pm

    Givler, Eric wrote:
    The problem is the
    user double clicks [login] and can get two calls to the service method
    to execute simultaneously. They both don't see a row, so they both do
    an INSERT. One of the inserts fails due to a PK on the username.


    See generateToken[1] and isTokenValid [2]. The token will be valid for
    only one request. What to do with the invalid request (also the latest)
    is up to you.

    [1]
    http://struts.apache.org/1.x/apidocs/org/apache/struts/action/Action.html#generateToken(javax.servlet.http.HttpServletRequest)
    [2]
    http://struts.apache.org/1.x/apidocs/org/apache/struts/action/Action.html#isTokenValid(javax.servlet.http.HttpServletRequest)

    Cheers,

    Manos

    ---------------------------------------------------------------------
    To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
    For additional commands, e-mail: user-help@struts.apache.org
  • Mufaddal Khumri at Jan 15, 2008 at 4:23 pm
    >

    Eric
    How would I prevent this from occurring?
    [Questions]
    1. Is it simply a matter of making my service an instance
    variable of this action and making the login method synchronized? 2.
    Are there situations where I would not want there to be a single
    service
    instance? Could it cause a bottleneck?
    One simple technique that has worked out well for me and will
    depend on your use case is to disable to login button after the first
    time the user clicks on it.




    ---------------------------------------------------------------------
    To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
    For additional commands, e-mail: user-help@struts.apache.org
  • Givler, Eric at Jan 15, 2008 at 6:37 pm
    I don't know why I overlooked that. All I had to do was put saveToken()
    in a calling action, and make sure I called saveToken again if any
    validation or system errors occurred when I was returning to the form.
    If the token is invalid, There was a nice thread here about it:
    http://www.jguru.com/faq/view.jsp?EID=779112.

    Thanks and apologies for not looking at this first - I guess I was going
    the more difficult route.

    Eric

    -----Original Message-----
    From: Manos Batsis
    Sent: Tuesday, January 15, 2008 10:02 AM
    To: Struts Users Mailing List
    Subject: Re: How do I prevent two calls concurrently?


    Givler, Eric wrote:
    The problem is the
    user double clicks [login] and can get two calls to the service method
    to execute simultaneously. They both don't see a row, so they both do
    an INSERT. One of the inserts fails due to a PK on the username.


    See generateToken[1] and isTokenValid [2]. The token will be valid for
    only one request. What to do with the invalid request (also the latest)
    is up to you.

    [1]
    http://struts.apache.org/1.x/apidocs/org/apache/struts/action/Action.htm
    l#generateToken(javax.servlet.http.HttpServletRequest)
    [2]
    http://struts.apache.org/1.x/apidocs/org/apache/struts/action/Action.htm
    l#isTokenValid(javax.servlet.http.HttpServletRequest)

    Cheers,

    Manos

    ---------------------------------------------------------------------
    To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
    For additional commands, e-mail: user-help@struts.apache.org


    ---------------------------------------------------------------------
    To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
    For additional commands, e-mail: user-help@struts.apache.org
  • Martin Gainty at Jan 15, 2008 at 7:21 pm
    provided if the comprehensive route is always the most difficult

    2 quick questions-
    1)In struts-2.0.11 has resetToken/saveToken/generateToken morphed into a
    different entity ?
    2)can I assume a session.invalidate() will effect a resetToken

    Thanks/
    Martin-
    ----- Original Message -----
    From: "Givler, Eric" <egivler@state.pa.us>
    To: "Struts Users Mailing List" <user@struts.apache.org>
    Sent: Tuesday, January 15, 2008 1:36 PM
    Subject: RE: How do I prevent two calls concurrently?


    I don't know why I overlooked that. All I had to do was put saveToken()
    in a calling action, and make sure I called saveToken again if any
    validation or system errors occurred when I was returning to the form.
    If the token is invalid, There was a nice thread here about it:
    http://www.jguru.com/faq/view.jsp?EID=779112.

    Thanks and apologies for not looking at this first - I guess I was going
    the more difficult route.

    Eric

    -----Original Message-----
    From: Manos Batsis
    Sent: Tuesday, January 15, 2008 10:02 AM
    To: Struts Users Mailing List
    Subject: Re: How do I prevent two calls concurrently?


    Givler, Eric wrote:
    The problem is the
    user double clicks [login] and can get two calls to the service method
    to execute simultaneously. They both don't see a row, so they both do
    an INSERT. One of the inserts fails due to a PK on the username.


    See generateToken[1] and isTokenValid [2]. The token will be valid for
    only one request. What to do with the invalid request (also the latest)
    is up to you.

    [1]
    http://struts.apache.org/1.x/apidocs/org/apache/struts/action/Action.htm
    l#generateToken(javax.servlet.http.HttpServletRequest)
    [2]
    http://struts.apache.org/1.x/apidocs/org/apache/struts/action/Action.htm
    l#isTokenValid(javax.servlet.http.HttpServletRequest)

    Cheers,

    Manos

    ---------------------------------------------------------------------
    To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
    For additional commands, e-mail: user-help@struts.apache.org


    ---------------------------------------------------------------------
    To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
    For additional commands, e-mail: user-help@struts.apache.org



    ---------------------------------------------------------------------
    To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
    For additional commands, e-mail: user-help@struts.apache.org

Related Discussions

Discussion Navigation
viewthread | post