#java #mysql #jdbc #dao #apache-commons-dbcp
Вопрос:
У меня есть dao, какие методы должны быть в пределах одной транзакции, как лучше всего это сделать правильно? Car dao имеет следующий метод
public Car findCar(int numOfPas,String carCategory){
String query = "SELECT*FROM car_info WHERE numOfPas = ? AND carCategory=? AND carState='ready' ORDER BY RAND() LIMIT 1;";
Car foundCar = null;
ResultSet resultSet = null;
try (Connection connection = MySQLDAOFactory.getConnection();
PreparedStatement statement = connection.prepareStatement(query)){
statement.setInt(1,numOfPas);
statement.setString(2,carCategory);
resultSet =statement.executeQuery();
if(resultSet.next()){
foundCar = new Car();
foundCar.setCarId(resultSet.getInt("carId"));
foundCar.setCarCategory(resultSet.getString("carCategory"));
foundCar.setNumOfPas(resultSet.getInt("numOfPas"));
foundCar.setCarState(resultSet.getString("carState"));
foundCar.setCarName(resultSet.getString("carName"));
foundCar.setCarImage(manager.byteToImage(resultSet.getBytes("carImage")));
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
if(resultSet!=null){
try {
resultSet.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
return foundCar;
}
И порядок Дао имеет следующее
@Override
public boolean insertOrder(Order order) {
int rowNum = 0;
String query = "INSERT INTO user_order(userId,carId,userAddress,userDestination,orderCost,orderDate) values(?,?,?,?,?,?)";
ResultSet keys = null;
try (Connection connection = MySQLDAOFactory.getConnection();
PreparedStatement statement = connection.prepareStatement(query,Statement.RETURN_GENERATED_KEYS)){
statement.setInt(1,order.getUserId());
statement.setInt(2,order.getCarId());
statement.setString(3, order.getUserAddress());
statement.setString(4, order.getUserDestination());
statement.setDouble(5,order.getOrderCost());
statement.setTimestamp(6, Timestamp.valueOf(order.getOrderDate()));
rowNum = statement.executeUpdate();
keys = statement.getGeneratedKeys();
if(keys.next()){
order.setOrderId(keys.getInt(1));
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return rowNum>0;
}
Как я могу поместить эти действия в одну транзакцию? Я получаю соединение через пул dhcp-соединений Apache.
Отредактированный
Это класс, в котором я получаю соединение публичный класс MySQLDAOFactory расширяет DAOFactory {
public static Connection getConnection(){
Connection conn = null;
try {
Context initContext = new InitialContext();
Context envContext = (Context) initContext.lookup("java:comp/env");
DataSource ds = (DataSource) envContext.lookup("jdbc/UsersDB");
conn = ds.getConnection();
} catch (NamingException | SQLException e) {
e.printStackTrace();
}
return conn;
}
@Override
public CarDao getCarDao() {
return new MySQLCarDao();
}
@Override
public UserDao getUserDao() {
return new MySQLUserDao();
}
@Override
public OrderDao getOrderDao() {
return new MySQLOrderDao();
}
@Override
public CarCategoryDao getCarCategoryDao() {
return new MySQLCarCategoryDao();
}
}
Ответ №1:
Существует множество различных способов управления транзакциями. Учитывая ваш код, самым простым способом было бы:
в try
квартале:
- Создайте свой
connection
в вызывающем абоненте, который обертывает оба вызова - Выполнять
connection.setAutoCommit(false)
- Вызовите каждый из методов
findCar()
иinsertOrder()
- Вызов
connection.commit();
в catch
блоке:
вызов connection.rollback()
Он connection
не создается вне этих функций, поэтому не забудьте удалить настройку подключения из каждой функции.