Changes between Version 2 and Version 3 of AdvancedApplicationDevelopment
- Timestamp:
- 07/03/26 14:34:46 (7 days ago)
Legend:
- Unmodified
- Added
- Removed
- Modified
-
AdvancedApplicationDevelopment
v2 v3 5 5 The prototype was extended in two main directions: 6 6 7 * multi-operation database transactions were added for scenarios where several related database changes must be executed as one unit of work;8 * database connection pooling was added using HikariCP, so the application does not create a new database connection manually for every operation.7 * database connection pooling was implemented using HikariCP; 8 * explicit transaction handling was added for use-cases that execute multiple related database operations. 9 9 10 10 The implementation affects the following source files: … … 20 20 === Description === 21 21 22 In the previous prototype version, the application used a direct JDBC connection. In Phase P8, the application was changed to use a database connection pool.23 24 Connection pooling is useful because database connections are expensive to create and close repeatedly. Instead of creating a new physical connection for every database operation, the application initializes a pool of reusable connections. The application then requests a connection from the pool, uses it for the current operation, and returns it to the pool automatically when the operation finishes.22 In the previous version of the prototype, the application used a direct JDBC connection. In Phase P8, the application was changed to use a database connection pool. 23 24 Connection pooling is useful because database connections are expensive to create repeatedly. Instead of creating a new physical database connection for every operation, the application initializes a pool of reusable connections. When a use-case needs database access, the application requests a connection from the pool, uses it, and then returns it to the pool. 25 25 26 26 The connection pool is implemented in the class: … … 30 30 }}} 31 31 32 The application initializes the pool after the user enters the database URL, database username, and database password. The pool is then used by the main application class when executing the implemented use-cases.32 The Maven configuration file ''pom.xml'' was also updated with the required HikariCP dependency. 33 33 34 34 === Implementation === 35 35 36 The application uses HikariCP as the connection pooling library. The dependency is included in the Maven configuration file ''pom.xml''. 37 38 The pool is initialized with the database connection parameters and a pool name. The console output confirms that the pool is started successfully. 36 The application initializes the connection pool after the user enters the database URL, database username, and database password. If the pool is created successfully, the application displays a confirmation message and then shows the main menu. 39 37 40 38 [[Image(p8_connection_pool_initialized.png, width=100%)]] 41 39 42 The important result shown in the screenshot is that the application no longer connects only through a single direct JDBC connection. Instead, it initializes the connection pool first and then successfully connects to the database.43 44 The application displays:40 The screenshot shows that the HikariCP connection pool starts successfully. The application then confirms that the database connection pool was initialized and that the database connection is successful. 41 42 The important confirmation messages are: 45 43 46 44 {{{ … … 50 48 }}} 51 49 52 After the pool is initialized, the main menu is displayed:50 After the connection pool is initialized, the application displays the main menu: 53 51 54 52 {{{ … … 64 62 === Usage in the application === 65 63 66 The application uses connections from the pool when executing database operations. The connection is obtained from the pool, used inside the selected use-case, and then closed in the Java code. Closing the connection does not close the physical database connection immediately; it returns the connection to the pool so that it can be reused. 67 68 This is used in the implemented use-cases: 69 70 * ''Search available rooms'' 64 The application uses connections from the pool in the implemented use-cases. A connection is requested from the pool before executing SQL statements. When the operation finishes, the connection is closed in the Java code, but this does not destroy the physical database connection. Instead, the connection is returned to the pool and can be reused. 65 66 This improves the structure of the application because database access is managed through a separate pooling class instead of being handled manually in every part of the application. 67 68 == Transactions == 69 70 Transactions are required when one logical operation contains multiple database operations that must succeed or fail together. 71 72 In this prototype, transactions are used in the following implemented use-cases: 73 71 74 * ''Create reservation request'' 72 75 * ''Approve or reject reservation'' 73 76 74 == Transactions == 75 76 Transactions are needed when one logical application operation modifies multiple related database tables. If one part of the operation succeeds and another part fails, the database must not remain in a partially modified state. 77 78 The Java application therefore uses explicit transaction control for the use-cases where several related database operations are executed together. 79 80 The transaction logic follows this structure: 77 The application uses explicit transaction control in Java. The general transaction structure is: 81 78 82 79 {{{ … … 94 91 }}} 95 92 96 This means that all database changes inside the transaction are saved only if the whole operation is successful. If an error occurs, all changes from that transaction are rolled back.93 This means that all database changes inside the transaction are saved only if the complete operation is successful. If an error occurs, the transaction is rolled back and the database is not left in a partially modified state. 97 94 98 95 == Transaction 1: Create reservation request == … … 100 97 === Data requirements description === 101 98 102 Creating a reservation request canrequire changes in more than one table.103 104 A reservation request mayinclude:99 Creating a reservation request may require changes in more than one table. 100 101 A reservation request can include: 105 102 106 103 * only a room; … … 108 105 * both a room and requested equipment. 109 106 110 When the requester creates a reservation with additional equipment, the application must insert a new recordinto:107 When the requester creates a reservation with additional equipment, the application must insert data into: 111 108 112 109 * ''project.reservations'' 113 114 and then insert one or more related records into:115 116 110 * ''project.reservation_equipment'' 117 111 118 These operations must be executed in one transaction. If the reservation is inserted successfully, but the equipment insert fails, the whole operation must be rolled back. Otherwise, the database could contain an incomplete reservation.112 These operations must be executed as one transaction. If the reservation is inserted but inserting the requested equipment fails, the whole operation should be rolled back. This prevents incomplete reservation data from being saved. 119 113 120 114 === Implementation === … … 124 118 The application performs the following steps: 125 119 126 1. The requester is selected from the displayed list of users. 127 2. The reservation date, start time, and end time are entered. 128 3. The requester chooses whether the reservation includes a room. 129 4. If a room is included, the application displays available rooms and the requester selects one of them. 130 5. The requester chooses whether additional/general equipment should be requested. 131 6. If equipment is requested, the application displays available equipment and the requester selects equipment items and quantities. 132 7. The application starts a transaction. 133 8. The application inserts the reservation into ''project.reservations''. 134 9. If requested equipment exists, the application inserts the related rows into ''project.reservation_equipment''. 135 10. If all SQL statements are successful, the transaction is committed. 136 11. If any SQL statement fails, the transaction is rolled back. 120 1. The requester chooses the option ''Create reservation request'' from the main menu. 121 2. The system displays a list of users. 122 3. The requester selects the requester from the list. 123 4. The system asks for the reservation date. 124 5. The requester enters the reservation date. 125 6. The system asks for the start time and end time. 126 7. The requester enters the requested time interval. 127 8. The system asks whether the reservation should include a room. 128 9. If the reservation includes a room, the system displays available rooms. 129 10. The requester selects one of the available rooms from the list. 130 11. The system asks whether additional/general equipment should be requested. 131 12. If equipment is requested, the requester selects equipment and requested quantity. 132 13. The application starts a transaction. 133 14. The application inserts a new record into ''project.reservations''. 134 15. If requested equipment exists, the application inserts corresponding records into ''project.reservation_equipment''. 135 16. If all operations are successful, the transaction is committed. 136 17. If an error occurs, the transaction is rolled back. 137 137 138 138 === Demo execution === 139 139 140 The following screenshot shows the creation of a reservation request with additional equipment.140 The following screenshot shows the successful execution of the create reservation transaction. 141 141 142 142 [[Image(p8_create_reservation_transaction_success.png, width=100%)]] 143 143 144 In this test, the requester creates a reservation for room ''LAB-1'' on ''2026-06-01'' from ''09:00'' to ''10:00'' and additionally requests ''HDMI Cable''. 145 146 The following screenshot shows that the reservation request was created successfully. 147 148 [[Image(p8_transaction_create_reservation_success.png, width=100%)]] 149 150 The application displays the generated reservation ID and the created reservation details. 144 In this test, the requester creates a reservation request through the Java prototype. The application displays available users and rooms, the requester selects values from the displayed lists, and the reservation request is created successfully. 145 146 The use-case demonstrates that the user does not need to remember internal database identifiers such as ''user_id'' or ''room_id''. Instead, the application lists the possible values and internally uses the selected database identifiers. 151 147 152 148 === Database verification === 153 149 154 The result can be verified in DBeaver by checking the base tables.150 The result can be verified in DBeaver by checking the created reservation and the requested equipment records. 155 151 156 152 {{{ … … 164 160 }}} 165 161 166 The following screenshot shows that the reservation was inserted into ''project.reservations'' and that the requested equipment was inserted into ''project.reservation_equipment''. 167 168 [[Image(p8_transaction_create_reservation_db_verification.png, width=100%)]] 162 The following screenshot shows the database verification after the transaction was executed. 163 164 [[Image(p8_create_reservation_database_verification.png, width=100%)]] 165 166 The screenshot confirms that the reservation was inserted into ''project.reservations''. If the reservation included additional requested equipment, the related records are also inserted into ''project.reservation_equipment''. 169 167 170 168 === Transaction discussion === 171 169 172 This operation is a transaction because the reservation and the requested equipment represent one logical request. The database should not contain requested equipment without the corresponding reservation, and it should not contain a partially created reservation if the equipment insert fails.170 This use-case requires a transaction because creating a reservation request is one logical operation, even when it modifies multiple tables. The reservation and its requested equipment must be saved together. If one part fails, the whole operation should be cancelled. 173 171 174 172 Therefore, the application commits the transaction only after all related inserts are successful. … … 178 176 === Data requirements description === 179 177 180 Approving or rejecting a reservation also requires m ore than one database change.178 Approving or rejecting a reservation also requires multiple related database operations. 181 179 182 180 When an approver makes a decision, the application must: 183 181 184 * update the status of the selected reservationin ''project.reservations'';185 * insert theapproval decision into ''project.approvals''.186 187 These two operations must be executed consistently. The reservation status and the approval record must alwaysmatch. If the approval record cannot be inserted, the reservation status should not remain changed.182 * update the reservation status in ''project.reservations''; 183 * insert a new approval decision into ''project.approvals''. 184 185 These two operations must be consistent. The reservation status and the approval record must match. If the approval record cannot be inserted, the reservation status should not remain changed. 188 186 189 187 === Implementation === … … 193 191 The application performs the following steps: 194 192 195 1. The approver opens the ''Approve or reject reservation'' optionfrom the main menu.196 2. The application lists allpending reservations.197 3. The approver selects a reservation from the displayedlist.198 4. The application lists users who are allowed toapprove reservations.193 1. The approver chooses the option ''Approve or reject reservation'' from the main menu. 194 2. The system displays a list of pending reservations. 195 3. The approver selects one reservation from the list. 196 4. The system displays a list of users who can approve reservations. 199 197 5. The approver selects the approving user. 200 6. The approver chooses either ''approved'' or ''rejected''.198 6. The approver chooses whether the reservation should be approved or rejected. 201 199 7. The approver enters an optional decision note. 202 200 8. The application starts a transaction. 203 9. The application updates the reservation status in ''project.reservations''.201 9. The application updates the selected reservation status in ''project.reservations''. 204 202 10. The application inserts a new approval record into ''project.approvals''. 205 203 11. If both operations are successful, the transaction is committed. … … 208 206 === Demo execution === 209 207 210 The following screenshot shows the approval process in the Java prototype. 211 212 [[Image(p8_transaction_approve_reservation_input.png, width=100%)]] 213 214 The approver selects a pending reservation, selects the approving user, chooses the decision, and enters the decision note. 215 216 The following screenshot shows the successful result of the approval transaction. 217 218 [[Image(p8_transaction_approve_reservation_success.png, width=100%)]] 219 220 The application displays the final reservation details, including the updated status, decision, decision time, and approver. 208 The following screenshot shows the successful execution of the approval transaction. 209 210 [[Image(p8_approval_transaction_success.png, width=100%)]] 211 212 The screenshot shows that the approver selects a pending reservation, chooses the approver user, enters the decision, and saves the approval decision. The application then displays the final reservation details. 221 213 222 214 === Database verification === … … 234 226 }}} 235 227 236 The following screenshot shows that the reservation status was updated and that the corresponding approval record was inserted. 237 238 [[Image(p8_transaction_approve_reservation_db_verification.png, width=100%)]] 228 The following screenshot shows the database verification after the approval transaction was executed. 229 230 [[Image(p8_approval_database_verification.png, width=100%)]] 231 232 The screenshot confirms that the reservation status was updated and that a corresponding approval record was inserted into ''project.approvals''. 239 233 240 234 === Transaction discussion === 241 235 242 This operation is a transaction because approval is not just one table change. The reservation status and approval decision must be saved together. If only the reservation status were updated without inserting an approval record, the database would lose information about who made the decision and when it was made.243 244 Therefore, the application treats the approval operation as one atomic unit of work.236 This use-case requires a transaction because approval is not only a single table change. The status update and the approval insert represent one logical decision. 237 238 If the reservation status were updated without inserting an approval record, the database would lose information about who made the decision, when the decision was made, and what note was entered. Therefore, both operations must be committed together or rolled back together. 245 239 246 240 == Rollback behavior == 247 241 248 The transaction implementation also protects the database from partial changes. If an error happens during a transaction, the application executes rollback. 249 250 For example, in the create reservation transaction, if the reservation insert succeeds but a related requested equipment insert fails, the reservation should not remain saved as an incomplete request. Similarly, in the approval transaction, if the reservation status update succeeds but the approval insert fails, the status update should be rolled back. 251 252 This behavior is important because it preserves database consistency. 253 254 [[Image(p8_transaction_rollback_test.png, width=100%)]] 255 256 The screenshot above demonstrates that an invalid or failing operation does not leave incomplete data in the database. 242 The transaction implementation protects the database from partial changes. 243 244 If an error occurs during the create reservation transaction, the inserted reservation and related requested equipment records are rolled back. If an error occurs during the approval transaction, the reservation status update and the approval insert are rolled back. 245 246 This behavior preserves database consistency because incomplete multi-step operations are not saved. 257 247 258 248 == Maven configuration == 259 249 260 The Maven configuration file ''pom.xml'' was updated to include the required dependencies for PostgreSQL JDBC and HikariCP. 261 262 The PostgreSQL JDBC driver is required so the Java application can connect to the PostgreSQL database. 263 264 HikariCP is required so the application can use database connection pooling. 250 The Maven configuration file ''pom.xml'' was updated to include the required dependencies. 251 252 The application uses: 253 254 * PostgreSQL JDBC driver for connecting to the PostgreSQL database; 255 * HikariCP for database connection pooling; 256 * SLF4J implementation for HikariCP logging. 265 257 266 258 The relevant configuration is stored in: … … 272 264 == Final discussion == 273 265 274 Phase P8 improves the Java prototype by adding application-leveltransaction handling and database connection pooling.266 Phase P8 improves the Java prototype by adding transaction handling and database connection pooling. 275 267 276 268 The most important improvements are: 277 269 278 * the application uses a reusable connection pool instead of relying on a single direct JDBC connection; 279 * the connection pool is initialized once and then reused by the implemented use-cases; 270 * the application uses HikariCP connection pooling; 271 * database access is centralized through ''DatabasePool.java''; 272 * the connection pool is initialized once and reused by the application; 280 273 * creating a reservation request is executed as a transaction; 281 * inserting requested equipment for a reservationis included in the same transaction as the reservation insert;274 * inserting requested equipment is included in the same transaction as the reservation insert; 282 275 * approving or rejecting a reservation is executed as a transaction; 283 * reservation status updates and approval record inserts are saved together;284 * rollback is used when a multi-step operation fails;285 * database consistency is preserved even when a use-case requires several SQL statements.286 287 These improvements make the prototype more reliable and closer to a real database application, while still keeping the application intentionally simple for the project phase.276 * reservation status updates and approval records are saved consistently; 277 * rollback is used when a multi-step database operation fails; 278 * the prototype is more reliable and closer to a real database application. 279 280 These additions satisfy the Phase P8 requirements because the application now demonstrates both database connection pooling and transactions for use-cases where multiple related database operations must be executed as one unit of work.
