|
| 1 | +# Coding Best Practices |
| 2 | + |
| 3 | +This document describes some typical programming pitfalls and best practices |
| 4 | +related to Java and JDBC. It will grow and change as we encounter new situations |
| 5 | +and the codebase evolves. |
| 6 | + |
| 7 | +## Correctness & Business Logic |
| 8 | + |
| 9 | +- Validate if the code adheres to what it is supposed to do. Compare the |
| 10 | + implementation with the specification and ask questions, to get clarity. |
| 11 | + |
| 12 | +## Memory / Resource Management |
| 13 | + |
| 14 | +- Use try-with-resources for managing ResultSet, Statement, Connection, streams, sockets, file handles. |
| 15 | +- Avoid unnecessary object creation in hot paths (tight loops, parsing routines). |
| 16 | +- Reuse preallocated buffers if available (e.g., for TDS packets). |
| 17 | +- Can memory usage be optimized? Is pooling or reuse possible? |
| 18 | + |
| 19 | +## Error Handling & Reliability |
| 20 | + |
| 21 | +- Catch specific exception types (SQLTimeoutException, IOException, etc.). |
| 22 | +- Wrap exceptions using SQLServerException.makeFromDriverError(...) or similar APIs. |
| 23 | +- Ensure logs are useful and include information such as connection ID or any state transitions. |
| 24 | +- Avoid catching the base Exception unless absolutely required. |
| 25 | + |
| 26 | +## Async, Concurrency & Thread Safety (if applicable) |
| 27 | + |
| 28 | +- Synchronize access to shared mutable state. |
| 29 | +- For background threads, handle interruption and termination gracefully. |
| 30 | +- Avoid deadlocks by keeping lock hierarchy consistent. |
| 31 | +- Are all shared variables properly synchronized or volatile ? |
| 32 | +- Are ExecutorServices or thread pools properly shut down? |
| 33 | + |
| 34 | +## Backward Compatibility |
| 35 | + |
| 36 | +- Verify unit tests and integration tests haven’t regressed (especially server compatibility tests). |
| 37 | +- Preserve public interfaces and behaviors unless part of a breaking release plan. |
| 38 | +- Annotate deprecated methods if replacing functionality. |
| 39 | +- Are any existing APIs modified or removed? If yes, is this justified and documented? |
| 40 | +- Could this change affect driver users on older SQL Server versions or JDBC clients? |
| 41 | +- Are test expectations changed in a way that signals a behavior shift? |
| 42 | + |
| 43 | +## Security Considerations |
| 44 | + |
| 45 | +- Never log passwords, secrets, or connection strings with credentials. |
| 46 | +- Validate inputs to avoid SQL injection, even on metadata calls. |
| 47 | +- Are there any user inputs going into SQL or shell commands directly? |
| 48 | +- Are secrets being logged or exposed in stack traces? |
| 49 | +- Are TLS/certificate settings handled safely and explicitly? |
| 50 | +- Are we sending unbounded data streams to server prior to authentication e.g. in feature extensions? |
| 51 | + |
| 52 | +## Performance & Scalability |
| 53 | + |
| 54 | +- Avoid blocking operations on performance-critical paths. |
| 55 | +- Profile memory allocations or TDS I/O if large buffers are introduced. |
| 56 | +- Use lazy loading for large metadata or result sets. |
| 57 | +- Will this impact startup, connection, or execution latency? |
| 58 | +- Could this increase memory usage, thread contention, or GC pressure? |
| 59 | +- Are any caches or pools growing unbounded? |
| 60 | +- For major features or large PRs, always run the internal performance benchmarks or performance |
| 61 | + testsuite to determine if the new changes are causing any performance degradation. |
| 62 | + |
| 63 | +## Observability (Logging / Tracing / Metrics) |
| 64 | + |
| 65 | +- Use existing logging framework (java.util.logging) for debug/trace with appropriate logging level. |
| 66 | +- Include connection/session ID when logging. |
| 67 | +- Ensure log messages are actionable and contextual. |
| 68 | +- Is the new code adequately traceable via logs? |
| 69 | +- Are any logs too verbose or leaking user data? |
| 70 | + |
| 71 | +## Unit Tests / Integration |
| 72 | + |
| 73 | +- Have you added unit tests and integration tests? |
| 74 | +- Unit tests should not depend on external resources. Code under unit test |
| 75 | + should permit mocked resources to be provided/injected. |
| 76 | +- Avoid tests that rely on timing. |
| 77 | + |
| 78 | + |
| 79 | +## Configuration & Feature Flags |
| 80 | + |
| 81 | +- Is the change considered a breaking change? If breaking change is not |
| 82 | + avoidable, has a Configuration/Feature flag been introduced for customers to |
| 83 | + revert to old behavior? |
| 84 | + |
| 85 | +## Code Coverage expectations |
| 86 | + |
| 87 | +- Does the new code have sufficient test coverage? |
| 88 | +- Are the core paths exercised (including error conditions and retries)? |
| 89 | +- If the code is untestable, is it marked as such and is there a reason (e.g., hard dependency on native SQL Server behavior)? |
| 90 | + |
| 91 | +## Pipeline runs |
| 92 | + |
| 93 | +- Is the CI passing? If not, then have you looked at the failures, and found the |
| 94 | + cause for failures? |
0 commit comments