-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTransactionManager.java
More file actions
169 lines (140 loc) · 5.32 KB
/
TransactionManager.java
File metadata and controls
169 lines (140 loc) · 5.32 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
package quickutils.transactionManager;
/**
*
* @author JIBOYE, Oluwagbemiro Olaoluwa <gbenroscience@yahoo.com>
*/
import java.sql.Connection;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* @author JIBOYE, Oluwagbemiro Olaoluwa <gbenroscience@yahoo.com>
*
This class helps manage a database transaction. There is an abstract method
* called process and 2 fully fledged methods called onSuccess and onError. The
* onSuccess method defines what should happen to the connection if the process
* method's implementation completes successfully while onError specifies what
* should happen to the connection if an error occurs.
*
* onSuccess triggers: A commit of all transactions AND a startTransaction to
* setAutoCommit(true) onError triggers: A rollback of all transactions AND a
* startTransaction to setAutoCommit(true)
*
* The method, process, returns true or false based on whether the transactions were successful
* or not. If the transactions were successful and so should be committed,
* return true. If you need to discard them, return false. If your method throws
* an exception, the {@link TransactionManager} is designed to startTransaction
* onError and so rollback the transactions and also return your Connection
* object to its autocommit=true state.
*
* IN YOUR IMPLEMENTATION OF process(), ANY PORTION OR LOGICAL BRANCH OF THE
* METHOD THAT SUGGESTS THAT A ROLLBACK IS NEEDED SHOULD IMMEDIATELY return
* false;
*
* There are 3 callbacks that can be used to determine the next course of action
* when the manager completes its transaction.
*
* The first is onCommit(), the second is onRollback(), the third is onRollback(int errorcode)
* The onCommit callback is guaranteed to be called if the transaction was totally successfull.
* The onRollback callback is guaranteed to be called if the transaction is detected to have failed in at least one point,
* either by an uncaught exception or by the user returning a false at any point in the process(conn) method.
* The overloaded version of onRollback is guaranteed to be called under similar circumstances as the first, but it returns
* an error-code which the user must have set before returning false or before a terminating exception is thrown.
*
* Anyone that wishes to handle generic errors would use onRollback().
* Only anyone that wants to handle particular errors(introduce granularity in error handling)
* should use onRollback(int). They MUST then set the error code before returning false.
*
*
*
*
*/
public abstract class TransactionManager {
/**
* The code to track in the rollback callback when something goes wrong
* to allow the user flexibility when handling errors.
*/
protected int errorCode;
/**
* No error occurred
*/
public static final int ERROR_NONE = Integer.MAX_VALUE;
/**
* If true, the transaction was committed successfully
*/
private boolean ok;
public void startTransaction(java.sql.Connection conn) {
try{
conn.setAutoCommit(false);
if (process(conn)) {
onSuccess(conn);
} else {
onError(conn);
}
} catch (Exception ex) {
ex.printStackTrace();
onError(conn);
}
}
public void setErrorCode(int errorCode) {
this.errorCode = errorCode;
}
/**
*
* @return true if the transactions were committed successfully and false
* otherwise.
*/
public boolean isOk() {
return ok;
}
/**
* Do the database transactions here.
*
* @param conn The Connection object
* @return true if the transaction should be committed; and false otherwise.
*/
protected abstract boolean process(java.sql.Connection conn);
/**
* Override to perform completion operations like writing to the client if the commit
* was successful
*/
public void onCommit() {
}
/**
* Override to perform error operations if the transaction failed. At this point, the manager has already rolled back the transactions.
* If the database transactions failed or if they succeeded but the call to
* commit failed.
*/
public void onRollback() {
}
/**
* Override to perform error operations if the transaction failed. At this point, the manager has already rolled back the transactions.
* If the database transactions failed or if they succeeded but the call to
* commit failed.
* @param errorCode The error code that caused the transaction to rollback
*/
public void onRollback(int errorCode) {
}
private void onError(Connection conn) {
try {
conn.rollback();
ok = false;
onRollback();
onRollback(errorCode);
conn.setAutoCommit(true);
} catch (Exception ex) {
Logger.getLogger(TransactionManager.class.getName()).log(Level.SEVERE, null, ex);
}
}
private void onSuccess(Connection conn) {
try {
conn.commit();
ok = true;
onCommit();
conn.setAutoCommit(true);
} catch (Exception ex) {
ex.printStackTrace();
Logger.getLogger(TransactionManager.class.getName()).log(Level.SEVERE, null, ex);
}
}
}