Say a user registers for your site, you hash the password they have chosen then use that hash as a salt and rehash their password with that salt.
Example:
String hash1 = MD5(password);
String endHash = MD5(hash1 + password);
then store endHash in your database. Would this effective agaisnt Rainbow Table attacks if my database was comprimized? Or am i missing something that would make it easy to break?
This is key strengthening (http://en.wikipedia.org/wiki/Key_strengthening), a nice technique that nonetheless does not substitute for actual salt. It will not protect you against a rainbow table written with this double-hash function.
The point of salting is to prevent the use of huge precalculated tables. With this method it is possible to calculate the hash of any password without the need to access your database. You should store a random value and hash the password and that value together.
The weakness of hashed passwords is the attacker's knowledge of your hash function. If they know your hash function but not your salt, the salt has protected your passwords. If they know both the hash function and your salt, your data is at risk.
As this applies to your question - using dynamic salt generally makes it more difficult to figure out your salt. This increases security, but won't help if someone knows your algorithm.
Increasing your complexity in this way does make your system harder to crack. Nothing is uncrackable given enough resources, however.
Instead of hashing two times you should use the username as salt for the function:
String hash = MD5(username + password)
You should also consider using a different function as md5 is considered broken MD5
Doesn't make a difference: Your stored data is still based exclusively on the password, so there's no additional protection.
Also, you should avoid MD5 in favor of a currently-strong hash algorithm, such as SHA1, SHA-256, SHA-512.