This. Especially the layers.
If you can, split the application in two parts - the font end running on a world-facing web server and a back end on a private network. Use a well-defined, high level protocol for communication between the two. If you can afford (literally, it's just a matter of throwing more hardware at the problem) some overhead, use a text-based serialization format with a solid, well-tested parser. The simpler, the better. Check every single request at the backend in every possible way, data sanity checking at the door is crucial. Maybe sign the requests - won't do any good if someone breaks into the frontend boxes (because they will get the private key then), but will make it impossible to somehow impersonate those boxes without compromising them first. Sign responses. Generate and deploy new keys and certificates often. Use prime numbers (look up cicada principle) for intervals between key changes to avoid being predictable, if you're truly paranoid. Log everything, offsite. Send the logs over a smart network bridge that will let through logs, just logs and only logs, and only in one direction just to be sure. Make this bridge the one and only thing connected to the log server, other than the power cable, a monitor, a keyboard and a tape drive. Preferably use a similar bridge between the frontend and the backend servers, have it do sanity checking of all passing traffic in addition to the checks at the backend. Have different people implement the checks at the backend and at the bridge, do not let them share code. Preferably, use two different parsers for your serialization format of choice. If you can, put the databases on a third layer behind the backend (so that it's only doing business logic, not data storage). Try to embed some basic security in the database itself, especially data integrity checks. Have it roll the transaction back, tell the backend to bugger off and raise an alarm if it's told to do something that doesn't quite fit with the nature of the data. And so on, and so on, and so on. It's all about assuming that every single part of the system can and will contain security holes, but with so many layers, cross-checks and variations on the security measures (like using two different parser implementations for the same check), the probability of someone finding a usable chain of exploits is absurdly low. Remember, exploits have to be used several at a time to actually break into a system and not just DoS it.
I wonder if any web applications that properly implement all those things and more even exist, but it wouldn't hurt to try to make one, if you have the funds.
Oh, and one last thing. The most important one, actually. If you pull this off, your application might be so impervious to hacking in the usual sense of the word that it would be simply impractical to do that, not worth the time and effort. And guess what the determined hacker will probably do at that point? Dress as an air conditioning serviceman, show up at the facility, talk some shit into the guard and walk away with your data 15 minutes later, using equipment no more high-tech than a screwdriver. Or, if your guards are not as dumb as that, a *very* determined hacker might even employ themselves at your air conditioning service, cleaning or electrical work company and do the same the next time they *legitimately* show up at the facility. It's been done. In short, consider other aspects of security, moreso if you're actually a valuable target and almost unhackable through the internet.