java: race conditions - is there a way to make sure several lines of code will be executed together?

痞子三分冷 提交于 2019-12-06 05:17:45

You could use a Lock object.

Using Lock objects has advantages over the more primitive synchronized blocks and methods.

You could synchronize the block of code, such that only one thread at a time could execute it. However, this doesn't seem like a very good solution, as it will slow down your application. You would like to have multiple users logging in concurrently.

How are tokens created? If you were to generate them on the server side in response to a user logging in, then one user shouldn't be able to use another user's token.

Sounds like you need a synchronized method / block:

See here for example (synchronized method)

http://java.sun.com/docs/books/tutorial/essential/concurrency/syncmeth.html

Be careful not to over-cook it the otherway ! Too much synchronization can lead to bottlenecking !

I'm not sure why you're creating a token for a login. Your question seems to imply this token is on the database and not in memory. If so, synchronization and mutexes won't really help, what you need is to lock the database record with a "select for update".

Maybe this gets into a lot of irrelevant complexity, but why are you creating a token to do a login? Any time I do a login, I simply collect the userid and password from the screen or incoming form, check against the database to see if the combination is valid, and if so let the user in. What do you need a token for?

You say that you "remove the token from the db". Is the database a SQL database? If so then you can use a transaction to avoid the race condition. It would look something like this:

  1. Create a unique session ID, e.g. UUID sessionID = UUID.randomUUID();
  2. Begin transaction
  3. Delete any tokens from the DB that match the one in the request, e.g.
    DELETE FROM Tokens WHERE TokenID = <requested-token>
  4. Get the affected row count
  5. If the affected row count is exactly 1, then the token was valid. Create a session, e.g.
    INSERT INTO Session VALUES (sessionUUID, userID, loginTime, ...)
  6. Commit transaction

Now if the login was successful (i.e. the affected row count was exactly 1), send the client a cookie containing the session ID.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!