JDBC: problème verrouillage pessimiste.
J'essaye d'utiliser dans mon exemple, un verrouillage pessimiste.
Voici les différents programmes utilisés:
*JDBCManager.java:
Code:
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();
}
}
}
} |
*PessimisticLockerA.java:
Code:
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);
}
}
} |
*PessimisticLockerB.java:
Code:
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);
}
}
} |
Pour faire fonctionner le programme, j'ouvre deux fenêtres et je configure le classpath dans chacune d'elle comme ceci:
Citation:
set classpath=.;C:\Sun\AppServer\pointbase\lib\pbclient.jar
Ensuite je tape cette commande dans une fenêtre:
Citation:
java -Djdbc.drivers=com.pointbase.jdbc.jdbcUniversalDriver Ch07.PessimisticLockerA
Puis celle-ci dans l'autre:
Citation:
java -Djdbc.drivers=com.pointbase.jdbc.jdbcUniversalDriver Ch07.PessimisticLockerB
J'exécute la première commande, j'ai ceci qui s'affiche:
Citation:
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
Je lance PessimisticLockerB, voici le message d'erreur:
Citation:
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)
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.
Enfin sur la première fenêtre, j'ai ces messages ci:
Citation:
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
Si quelqu'un peut m'éclairer, je suis preneur.
Merci d'avance, mumu27!