J'essaye d'utiliser dans mon exemple, un verrouillage pessimiste.
Voici les différents programmes utilisés:
*JDBCManager.java:
*PessimisticLockerA.java:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 package Ch07; import java.sql.*; import java.util.*; public class JDBCManager { private JDBCManager() { } public static Connection getConnection(String url) throws SQLException { return getConnection(url, true); } public static Connection getConnection(String url, boolean autocommit) throws SQLException { Connection connection = DriverManager.getConnection(url); connection.setAutoCommit(autocommit); return connection; } public static Connection getConnection( String url, String user, String password) throws SQLException { return getConnection(url, user, password, true); } public static Connection getConnection( String url, String user, String password, boolean autocommit) throws SQLException { Connection connection = DriverManager.getConnection(url, user, password); connection.setAutoCommit(autocommit); return connection; } public static Connection getConnection(String url, Properties props) throws SQLException { return getConnection(url, props, true); } public static Connection getConnection( String url, Properties props, boolean autocommit) throws SQLException { Connection connection = DriverManager.getConnection(url, props); connection.setAutoCommit(autocommit); return connection; } public static void rollback(Connection conn) { try { conn.rollback(); } catch (Exception e) { e.printStackTrace(); } } public static void close(Connection conn) { if (conn != null) { try { conn.close(); } catch (Exception e) { e.printStackTrace(); } } } public static void close(Statement stmt) { if (stmt != null) { try { stmt.close(); } catch (Exception e) { e.printStackTrace(); } } } public static void close(ResultSet rset) { if (rset != null) { try { rset.close(); } catch (Exception e) { e.printStackTrace(); } } } }
*PessimisticLockerB.java:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 package Ch07; import java.sql.*; public class PessimisticLockerA { static Connection conn; static Statement stmt; static Statement stmtA; static PreparedStatement pstmt; static ResultSet rsetA; static String sqlCreate = "create table RESERVE " + "(ROOMID varchar(5), RES_DATE date, RES_FLAG boolean, " + "RES_NAME varchar(30))"; static String sqlInsert = "insert into RESERVE values " + "(?, ?, ?, ?)"; static String sqlUpdate = "update RESERVE set RES_FLAG=?, " + "RES_NAME=? WHERE ROOMID=? AND RES_DATE=?"; static String sqlSelect = "select ROOMID, RES_DATE, " + "RES_FLAG, RES_NAME from RESERVE WHERE RES_FLAG=false FOR UPDATE"; static String roomName; static java.sql.Date roomDate; public static void main(String[] args) { try { String url = "jdbc:pointbase:server://localhost/pointbaseDB"; String username = "PBPUBLIC"; String password = "PBPUBLIC"; conn = JDBCManager.getConnection(url, username, password, false); System.out.println("conn autocommit : " + conn.getAutoCommit()); setup(); userAQuery(); System.out.println("Interruption de 15 second, " + "Lancer PessimisticLockerB"); try {Thread.sleep(15000);} catch (Exception e) {} System.out.println("PessimisticLockerA est actif"); userAUpdate(); } catch (Exception e) { e.printStackTrace(); } finally { JDBCManager.close(conn); } } static void setup() throws SQLException { System.out.println("Creation de la table RESERVE"); try { stmt = conn.createStatement(); stmt.addBatch(sqlCreate); stmt.executeBatch(); System.out.println("Insertion d'une ligne de donnees"); pstmt = conn.prepareStatement(sqlInsert); pstmt.setString(1, "PIKE"); pstmt.setDate(2, new java.sql.Date(System.currentTimeMillis())); pstmt.setBoolean(3, false); pstmt.setNull(4, java.sql.Types.VARCHAR); pstmt.executeUpdate(); conn.commit(); } finally { JDBCManager.close(pstmt); JDBCManager.close(stmt); } } static void userAQuery() throws SQLException { System.out.println("L'utilisateur A demande une chambre"); stmtA = conn.createStatement(); rsetA = stmtA.executeQuery(sqlSelect); if (rsetA.next()) { System.out.println("La requete retourne une ligne"); roomName = rsetA.getString(1); roomDate = rsetA.getDate(2); } // Ni l'objet Statement ni l'objet ResultSet ne sont fermés ici // Ils doivent rester ouverts userAUpdate() } static void userAUpdate() throws SQLException { try { if (roomName != null && roomDate != null) { System.out.println("L'utilisateur A tente de réserver la chambre"); pstmt = conn.prepareStatement(sqlUpdate); pstmt.setBoolean(1, true); pstmt.setString(2, "Utilisateur A"); pstmt.setString(3, roomName); pstmt.setDate(4, roomDate); int result = pstmt.executeUpdate(); if (result == 0) { System.out.println("La réservation n'a PAS réussi !"); System.out.println("L'utilisateur devra essayer avec " + "une autre chambre ou une autre date"); } else { System.out.println("Validation pour l'utilisateur A"); conn.commit(); } } } catch (SQLException e) { e.printStackTrace(DriverManager.getLogWriter()); System.out.println(e.getErrorCode()); System.out.println(e.getMessage()); } finally { JDBCManager.close(pstmt); JDBCManager.close(rsetA); JDBCManager.close(stmtA); } } }
Pour faire fonctionner le programme, j'ouvre deux fenêtres et je configure le classpath dans chacune d'elle comme ceci:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 package Ch07; import java.sql.*; public class PessimisticLockerB { static Connection conn; static Statement stmt; static Statement stmtB; static PreparedStatement pstmt; static ResultSet rsetB; static String sqlUpdate = "update RESERVE set RES_FLAG=?, " + "RES_NAME=? WHERE ROOMID=? AND RES_DATE=?"; static String sqlSelect = "select ROOMID, RES_DATE, " + "RES_FLAG, RES_NAME from RESERVE WHERE RES_FLAG=false FOR UPDATE"; static String roomName; static java.sql.Date roomDate; public static void main(String[] args) { try { String url = "jdbc:pointbase:server://localhost/pointbaseDB"; String username = "PBPUBLIC"; String password = "PBPUBLIC"; conn = JDBCManager.getConnection(url, username, password, false); System.out.println("conn autocommit : " + conn.getAutoCommit()); userBQueryAndUpdate(); } catch (Exception e) { e.printStackTrace(); } finally { JDBCManager.close(conn); } } static void userBQueryAndUpdate() throws SQLException { System.out.println("L'utilisateur B tente de réserver la chambre"); try { stmtB = conn.createStatement(); rsetB = stmtB.executeQuery(sqlSelect); if (rsetB.next()) { System.out.println("L'utilisateur B réserve une chambre"); pstmt = conn.prepareStatement(sqlUpdate); pstmt.setBoolean(1, true); pstmt.setString(2, "User B"); pstmt.setString(3, rsetB.getString(1)); pstmt.setDate(4, rsetB.getDate(2)); pstmt.executeUpdate(); System.out.println("Validation pour l'utilisateur B"); conn.commit(); } else { System.out.println("Pas de chambre disponible pour l'utilisateur B"); } } catch (SQLException e) { e.printStackTrace(); System.out.println(e.getErrorCode()); System.out.println(e.getMessage()); } finally { JDBCManager.close(pstmt); JDBCManager.close(rsetB); JDBCManager.close(stmtB); } } }
Ensuite je tape cette commande dans une fenêtre:set classpath=.;C:\Sun\AppServer\pointbase\lib\pbclient.jar
Puis celle-ci dans l'autre:java -Djdbc.drivers=com.pointbase.jdbc.jdbcUniversalDriver Ch07.PessimisticLockerA
J'exécute la première commande, j'ai ceci qui s'affiche:java -Djdbc.drivers=com.pointbase.jdbc.jdbcUniversalDriver Ch07.PessimisticLockerB
Je lance PessimisticLockerB, voici le message d'erreur:conn autocommit : false
Creation de la table RESERVE
Insertion d'une ligne de donnees
L'utilisateur A demande une chambre
La requete retourne une ligne
Interruption de 15 second, lancer PessimisticLockerB
Là j'avoue que je ne comprends pas très bien, le programme semblait correct, puisque le JDBCManager avait été essayé sur un précédent programme qui marchait très bien.java.sql.SQLException: No suitable driver
at java.sql.DriverManager.getConnection(DriverManager.java:532)
at java.sql.DriverManager.getConnection(DriverManager.java:532)
at Ch07.JDBCManager.getConnection(JDBCManager.java:34)
at Ch07.PessimisticLockerB.main(PessimisticLockerB.java:27)
Enfin sur la première fenêtre, j'ai ces messages ci:
Si quelqu'un peut m'éclairer, je suis preneur.PessimisticLockerA est actif
L'utilisateur A tente de réserver la chambre
La réservation n'a PAS réussi
L'utilisateur devra essayer avec une autre chambre ou une autre date
Merci d'avance, mumu27!
Partager