I am sure there are various similar questions regarding this. But I am still not sure about the atomicity in Spring boot JDBC.
So my project is a Basic Online Cloth Store. Where the user adds some products into the cart and then checkout. Each user has some credits (virtual money).
So to implement checkout I need to execute Atomic operation on the Database. Basically, there are two things that I have to check while checkout.
User has enough credits while checkout.
There is enough stock.
So instead of doing normal JDBCtemplate.update(), I performed the queries and update by obtaining Connection and Then using Prepared statement. Below is my code for the checkout function.
public boolean validCart(String username) throws SQLException {
Connection conn = DataSourceUtils.getConnection(template.getDataSource());
try {
conn.setAutoCommit(false);
PreparedStatement ps = conn.prepareStatement("SELECT credits from user where username = ?");
ps.setString(1, username);
ResultSet rs = ps.executeQuery();
rs.next();
int credits = rs.getInt(1);
ps = conn.prepareStatement("SELECT cart.quantity*stock.price from cart,stock where cart.username = ? and stock.cloth_id = cart.cloth_id and stock.size = cart.size");
ps.setString(1, username);
rs = ps.executeQuery();
rs.next();
int cost = rs.getInt(1);
Boolean flag = false;
if(credits >= cost){
String sql = "SELECT COUNT(*) from cart,stock where cart.username = ? and cart.size = stock.size and cart.cloth_id = stock.cloth_id and cart.quantity > stock.quantity";
ps = conn.prepareStatement(sql);
ps.setString(1, username);
rs = ps.executeQuery();
rs.next();
int bad = rs.getInt(1);
sql = "SELECT COUNT(*) FROM cart WHERE username = ? and (cloth_id,size) NOT IN (SELECT cloth_id,size from stock)";
ps = conn.prepareStatement(sql);
ps.setString(1, username);
rs = ps.executeQuery();
rs.next();
bad += rs.getInt(1);
if(bad == 0){
sql = "UPDATE cart INNER JOIN stock on cart.cloth_id = stock.cloth_id and stock.size = cart.size SET stock.quantity = stock.quantity - cart.quantity where cart.username = ?";
ps = conn.prepareStatement(sql);
ps.setString(1, username);
ps.executeUpdate();
sql = "UPDATE user SET credits = credits - ? where username = ?";
ps = conn.prepareStatement(sql);
ps.setInt(1, cost);
ps.setString(2, username);
ps.executeUpdate();
sql = "INSERT INTO order_details(username,cloth_id,size,quantity,price) SELECT cart.username,cart.cloth_id,cart.size,cart.quantity,stock.price from cart,stock where cart.username = ? and cart.cloth_id = stock.cloth_id and cart.size = stock.size";
ps = conn.prepareStatement(sql);
ps.setString(1, username);
ps.executeUpdate();
sql = "DELETE FROM cart WHERE username = ?";
ps = conn.prepareStatement(sql);
ps.setString(1, username);
ps.executeUpdate();
flag = true;
}
}
conn.commit();
conn.setAutoCommit(true);
return flag;
} catch (SQLException e) {
conn.rollback();
e.printStackTrace();
}
return false;
}
But I am still not sure If operations are atomic that is the problem of race condition will not happen here.
And what should be the best method to perform this type of operation in general?.
Related
I am trying to make a java program can call a table by its name... but the problem is I couldnt figure out how to check if the table is exist or not in database... I am using phpmyadmin data base and here is my code if there is someone can help me ...
enter image description here
public boolean istableNameexist(String un){
boolean uexist = false;
Connection con = myConnection.getconnection();
PreparedStatement ps;
ResultSet rs;
try {
ps = con.prepareStatement("SELECT * FROM `javacontactapp` WHERE TABLE_NAME = ?");
ps.setString(1,name.getText());
rs = ps.executeQuery();
if (rs.next()){
uexist = true;
}
} catch (Exception e) {
System.out.println("wrong");
}
return uexist;
}
public void openfatura(ActionEvent actionEvent) {
String ff1 = name.getText();
Connection con = myConnection.getconnection();
if (!name.getText().isEmpty()) {
if (istableNameexist(name.getText())){
try {
PreparedStatement ps = con.prepareStatement("SELECT `dafat`, `sinif` ,`number` , `price`, `type`, `total` FROM " + ff1 + " WHERE `id` = 1");
ResultSet resultset = ps.executeQuery();
I have a SQL Server 2008 database and I want to select data by using a String variable... here is the selection code in java:
try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection con = DriverManager.getConnection("jdbc:odbc:DDS_DSN");
Statement st = con.createStatement();
ResultSet rs;
rs = st.executeQuery("SELECT source_port FROM request_dns WHERE destination_port = 53");
while ( rs.next() ) {
String source_port = rs.getString("source_port");
System.out.println(source_port);
}
con.close();
} catch (Exception e) {
System.out.println(e);
}
I want to make it like this:
String x = "53";
try
{
.
.
rs = st.executeQuery("SELECT source_port FROM request_dns WHERE destination_port = x");
.
.
}
could you please tell me how to do that?...
Thank you
Kind Regards
You want a parameterized query, like this:
int x = 53;
PreparedStatement ps = con.prepareStatement(
"SELECT source_port FROM request_dns " +
"WHERE destination_port = ?");
ps.setInt(1, x);
ResultSet rs = ps.executeQuery();
I have
employee(id, name, company, salary);
Need to display data for given id
public static void Connect(String conString, String username, String password, int id) throws SQLException{
try {
Class.forName("com.mysql.jdbc.Driver");
Connection conn = null;
conn = DriverManager.getConnection(conString, username, password);
String query = "select * from employee where id = " + id + "" ;
ResultSet rs = null;
Statement stmt = null;
stmt = conn.createStatement();
rs = stmt.executeQuery(query);
while(rs.next()){
String name = rs.getString("name");
String company = rs.getString("company");
int salary = rs.getInt("salary");
System.out.println("Name: " + name + "\tCompany: " + company + "\tSalary: " + salary);
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
But here we are passing the id directly. How can we pass it like parametrized queries (like how we pass ? during PreparedStatement)
in that case your query should be
String query = "select * from employee where id = ?";
instead of Statement you need to create PreparedStatement
PreparedStatement preparedStatement = conn.prepareStatement(query);
and then set your id to the prepared statement
preparedStatment.setInt(1, id);
finally execute the query
resultSet = preparedStatement.executeQuery();
It's old post but I would still like to add my answer.
I don't have enough reputation to comment on #prasad's answer, so I am adding small correction as separate answer. Actually, passing query inside praparedStatement.executeQuery() throws MySQLSyntaxErrorException because still it calls Statement.executeQuery instead of PreparedStatement.executeQuery(). And how do I know? I had to spent ample amount of time in figuring out this issue.
So use PreparedStatement.executeQuery() instead of PreparedStament.executeQuery(query).
I don't know why but the table doesnot display. Values are being added into base table in mysql but it doesnot display in jtable.
Connection con = null;
Statement stmt = null;
try{
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection(DB_URL, USER, PASS);
stmt = con.createStatement();
String sql = "insert into customers "+
"values("+id+", \""+name+"\", "+"\""+add+"\", "+pno+");";
stmt.executeUpdate(sql);
ResultSet rs = stmt.executeQuery("Select * from customers;");
DefaultTableModel model = new DefaultTableModel();
JTable table = new JTable(model);
JScrollPane scrollPane = new JScrollPane(table);
model.addColumn("CustID");
model.addColumn("CustName");
model.addColumn("CustAdd");
model.addColumn("PhoneNo");
while(rs.next()){
int tid = rs.getInt("custid");
String tname = rs.getString("custname");
String tadd = rs.getString("custadd");
long tpno = rs.getLong("phoneno");
model.addRow(new Object[]{tid, tname, tadd, tpno});
}
table.setVisible(true);
}catch(SQLException se){
jOptionPane1.showMessageDialog(this, se);
}catch(Exception e){
.
.
.
You add the JTable to the JScrollPane, but it does not look like you are adding the JScrollPane to anything. (Unless there is code that we are not seeing.)
I have a mySQL table named userinfo with colums- userId, userName, Password, city, age- userId is Pkey and Autoincremnt
When a user Login on a login.jsp, he submits username and Pasword.
These two parameters of login.jsp are received in UserLogin servlet and then checked in userinfo Table. If matched, he could log in.
I tried SELECT but I get numerous error. What should be the correct way:-
try {
String sql = "Select UserName, UserPW From SocialNetwork.RegisteredUser";
conn = ConnectionFactory.getConnection();
PreparedStatement ptmt = (PreparedStatement) conn
.prepareStatement(sql);
ptmt.executeQuery();
Statement stmt = (Statement) conn.createStatement();
s = connection.prepareStatement("select id_usuario, id_grupo from usuarios_grupos where id_grupo = ?");
//storing user data in ResultSet
ResultSet rs = stmt.executeQuery(sql);
while (rs.next()) {
String refName = rs.getString("UserName");
String refPass = rs.getString("UserPW");
if (user.equals(refName) && pw.equals(refPass) ) {
out.println("<html>");
out.println("<body>");
out.println("You are In");
out.println("</body>");
out.println("</html>");
System.out.println("sucess");
}
}
}catch (SQLException e) {
e.printStackTrace();
}
by using Statement interface you can not dynamically set the values. use PreparedStatement interface for second query.
import package in you class import javas.sql.*;
try {
String sql = "Select UserName, UserPW From SocialNetwork.RegisteredUser UserName = ?";
conn = ConnectionFactory.getConnection();
PreparedStatement ptmt =conn.prepareStatement(sql);
ptmt.setString(1, user)
ResultSet rs= ptmt.executeQuery();
while (rs.next()) {
String refName = rs.getString(1);//field index of user name
String refPass = rs.getString(2);//field index of password
if (user.equals(refName) && pw.equals(refPass) ) {
out.println("<html>");
out.println("<body>");
out.println("You are In");
out.println("</body>");
out.println("</html>");
System.out.println("sucess");
}
}
}catch (SQLException e) {
e.printStackTrace();
}
Are you asking for the entire code listing? in your current code you seem to be executing some queries for no reason, then getting a list of all users and iterating through them looking for a match. Try using a query like
sql ="Select UserName, UserPW From SocialNetwork.RegisteredUser where UserName=?"
ResultSet rs = stmt.executeQuery(sql);
then check the password in code
if(rs.next()){
String refPass = rs.getString("UserPW");
if (pw.equals(refPass) )
}