Chris, On 2/18/19, Christopher Schultz <ch...@christopherschultz.net> wrote: > -----BEGIN PGP SIGNED MESSAGE----- > Hash: SHA256 > > John, > > On 2/18/19 07:45, John Dale wrote: >> I agree - release your connection, commit transaction (if you have >> auto-commit set to false), and null-out your connection >> references. >> >> The analogy in c++ is you need deallocate memory. > > Deallocation of memory is a bad analogy, here. The better analogy for > C++ is ... returning a connection to a connection pool in C++. The > general term for this is "resource management", and it's important in > every programming language ever. > >> Java has GC in Java at a base level, but we also have some >> resource reclamation at higher levels of abstraction over which GC >> has no purview. Pooling (threads, connections) is an example. >> The connection pool needs to reclaim its connections for >> reallocation to other threads. If it can't, the application will >> hang waiting for connections. > > Exactly. > >> Do you have a static references to a database connection? >> >> The golden rule with database connections is acquire them late and >> release them early. I like to create try/catch/finally blocks. > > You must use try/catch/finally. Otherwise, you will leak resources. > >> In the finally block, which executes even if there is an >> exception, I commit the transaction and set connection reference to >> null. > > Compilers and static analyzers will often give you dead-store warnings > for null values, but I disagree with them that dead-stores are *bad*. > If you add code to the end of the method which makes the dead-store > into a LIVE-store, but the resource (e.g. ResultSet) shouldn't be used > anymore, it becomes a bug. An NPE is better than a use-after-free > (which isn't really a thing in Java like in other languages, but > practically it can have a similar effect). > > I wouldn't always commit the transaction in the finally block. That > can be wasteful at best and incorrect at worst. You commit should > (usually) only occur if no exceptions are encountered. All other > situations (usually) require a rollback.
There are some cases where the logic is more nuanced where I commit the transaction inside the try. For 99% of the cases in my code, the commit should come at the end of the try block, where the next line of execution is the first line of the finally block anyway. I do this for consistency and readability, but your point is well taken. FWIW, rollbacks occur in the catch block as required. As an engineering artist, this is kind of my signature, I suppose. I'm sure there are cases that I will encounter that will require some transactional gymnastics. I love Java IS middleware coding with Tomcat. I feel like there is no challenge too great to accommodate. > >> As a matter of course, I would null out and close references to >> PreparedStatements and ResultSets as well (especially ResultSets). > > This is 100% required for some drivers. The JDBC spec explicitly > allows for drivers to leak these resources if you do not clean them up > properly... especially if you are using pooled-connections (which IS > the case, here). I have seen some drivers (MySQL) which seem to > clean-up the mess and others (Oracle) which can cause problems not > only on the client, but also on the server ("Too many open cursors"). I've developed some patterns that make this easy for the coding that I'm doing including asking a Connection wrapper class for a PreparedStatement and passing in a SQL statement. Then, the connection wrapper registers the PS. After processing, when calling cleanup() I commit if necessary, and all PS's are closed accordingly. I handle ResultSets similarly by calling a function to register the RS with the connection, which handles the RS's on cleanup() as well. rollback() functions as expected in this context. Thanks for the comments. > > - -chris > -----BEGIN PGP SIGNATURE----- > Comment: Using GnuPG with Thunderbird - https://www.enigmail.net/ > > iQIzBAEBCAAdFiEEMmKgYcQvxMe7tcJcHPApP6U8pFgFAlxrCWQACgkQHPApP6U8 > pFhnOhAAvZeMADzrIz3x28CZjjBE2Hw2xEc9pEIeBaJVUTsPkjIHDQdTWNruxasz > NkW8T6hXkHRexoEqq6aLTrjtlaQmOawjvdvDzkF0+b7BvrUSBjAmpB4ai02FSZ/Y > vBvDXFgqthHxPYL9ykP3LlTaV2a4g+noDkVj862++AFhsVzEwZzW3cuQsegwoRs2 > pmEFIH9ZxGeD3OM5+2TdzUTdTGyc49OcmmI0UzKRFF1iZxmhBuuBDijvdW0OA+2K > WVq+RhCeqKclAGXOV9OIBSTewQaLVL5fgujlJxRDG7xW3oBsnfOc0SzipDMkXXsy > QpZQGzbx8XnaeEnFE7m5gqL0bxnen31pcrF3NigCPw75rOHbOTxO2pSvlRpSK6xq > WV8Wieytwq0Bc691TnmAibmx5wVMjqiFlXLmzd3wNlVMxHf9NmxmoWNfzqX03YZs > 44tj/tko5ukOJcI8oyhDeVKuGA8T57gU0qHl/aAgxunBmCSJiizoPc/8UcR577jj > ZLSrG1Fk/SXa1opzDZyOZbiG8apZX5V3oWmfcmyoLTIq0I46waTDBd3MohWmAm9t > stp0oLlCgmv9ydJK7VptiTXcTBYjfFn5sMEmcBx6Mp+Z3GexaX9gZx5dGNPFMa8v > 3LboKGJ27V4mc60g8yUd+4MiK+09xlQcbsILIhCH2mcWy+YOkdo= > =Df7E > -----END PGP SIGNATURE----- > > --------------------------------------------------------------------- > To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org > For additional commands, e-mail: users-h...@tomcat.apache.org > > --------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org