IT Research Department @BKAP 2015 Page 1 / 20 Lab 12 Concurrency, Listeners and Caching Mục tiêu - Optimistic locking dùng version attribute - Tạo Web Client để test Concurrent truy
Trang 1IT Research Department @BKAP 2015 Page 1 / 20
Lab 12
Concurrency, Listeners and Caching
Mục tiêu
- Optimistic locking dùng version attribute
- Tạo Web Client để test Concurrent truy cập vào Entity Class
Phần I Bài tập step by step
Bài 8.1 Xây dựng ứng dụng tích điểm thưởng cho khách hàng
Step 1: Tạo table Customer trong Database ConcurrencyDB
Step 2: Tạo JDBC ConnectionPool ConcurrencyPool và JDBC Resources jdbc/Concurrency
Trang 2Step 3: Tạo ứng dụng Enterprise ConcurrencyApp
Step 4: Tạo Entity Class Customer.java từ JDBC Resources jdbc/Concurrency
ConcurrencyApp-ejb Source Packages Persistence Entity Class (Package: entity)
Customer.java
Trang 3IT Research Department @BKAP 2015 Page 3 / 20
package entity;
import java.io.Serializable;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.persistence.Version;
import javax.xml.bind.annotation.XmlRootElement;
/**
*
* @author Quang
*/
@Entity
@Table(name = "Customer")
@XmlRootElement
@NamedQueries({
@NamedQuery(name = "Customer.findAll", query = "SELECT c FROM Customer c"),
@NamedQuery(name = "Customer.findById", query = "SELECT c FROM Customer c WHERE c.id = :customerId"), @NamedQuery(name = "customer.findByCustomerName", query = "SELECT c FROM Customer c WHERE
c.customerName like :customerName"),
@NamedQuery(name = "customer.findByRewardPts", query = "SELECT c FROM Customer c WHERE c.rewardPts = :rewardPts")
})
public class Customer implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "CustomerId")
private Long id;
@Column(name = "CustomerName")
private String customerName;
@Column(name = "RewardPts")
private int rewardPts;
@Version
private Long vesion;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getCustomerName() {
return customerName;
}
Trang 4public void setCustomerName(String customerName) {
this.customerName = customerName;
}
public int getRewardPts() {
return rewardPts;
}
public void setRewardPts(int rewardPts) {
this.rewardPts = rewardPts;
}
public Long getVesion() {
return vesion;
}
public void setVesion(Long vesion) {
this.vesion = vesion;
}
@Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
@Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Customer)) {
return false;
}
Customer other = (Customer) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
@Override
public String toString() {
return "entity.Customer[ id=" + id + " ]";
}
}
Step 5: Tạo Stateless Session Bean với Local Interface tên là RewardPtsModify
ConcurrencyApp-ejb Source Packages new Other Enterprise JavaBeans Session Bean
Trang 5IT Research Department @BKAP 2015 Page 5 / 20
RewardPtsModifyLocal.java
package beanpack;
Trang 6import entity.Customer;
import javax.ejb.Local;
/**
*
* @author Quang
*/
@Local
public interface RewardPtsModifyLocal {
public void multiplyPts(Customer customer, int modifier);
public void addPts(Customer customer, int modifier);
public void addCustomer(String customerName, int startPoints);
public void rapidMultiply(Customer customer, int times) throws Exception;
public void rapidAdd(Customer customer, int times) throws Exception;
public Customer getCustomer(String customerName);
public void resetPoints(Customer customer);
public void setLocking(boolean lockingEnable);
}
RewardPtsModify.java
package beanpack;
import entity.Customer;
import entity.Customer_;
import javax.ejb.Stateless;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;
import javax.persistence.EntityManager;
import javax.persistence.LockModeType;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
/**
*
* @author Quang
*/
@Stateless
@TransactionManagement(TransactionManagementType.CONTAINER)
public class RewardPtsModify implements RewardPtsModifyLocal {
@PersistenceContext(unitName = "ConcurrencyApp-ejbPU")
EntityManager em;
Trang 7
IT Research Department @BKAP 2015 Page 7 / 20
private boolean lockingEnable;
@Override
public void multiplyPts(Customer customer, int modifier) {
customer.setRewardPts(customer.getRewardPts() * modifier);
}
@Override
public void addPts(Customer customer, int modifier) {
customer.setRewardPts(customer.getRewardPts() + modifier);
}
@Override
public void addCustomer(String customerName, int startPoints) {
Customer customer = new Customer();
customer.setCustomerName(customerName);
customer.setRewardPts(startPoints);
em.persist(customer);
}
@Override
public void rapidMultiply(Customer customer, int times) throws Exception {
//Get a managable entity reference
customer = em.getReference(Customer.class, customer.getId());
//If locking is set as enabled, set an OPTIMISTIC Lock
if (lockingEnable) {
em.lock(customer, LockModeType.OPTIMISTIC);
}
//Repeatedely multiply the point with the modifier of 2
for (int i = 0; i < times; i++) {
multiplyPts(customer, 2);
Thread.sleep(2000);
}
if lockingEnable) {
em.lock(customer, LockModeType.NONE);
}
}
@Override
public void rapidAdd(Customer customer, int times) throws Exception {
//Get a managable entity reference
customer = em.getReference(Customer.class, customer.getId());
//If locking is set as enabled, set an OPTIMISTIC Lock
if (lockingEnable) {
em.lock(customer, LockModeType.OPTIMISTIC);
}
//Repeatedely increment the points with the modifier of 1
for (int i = 0; i < times; i++) {
addPts(customer, 1);
Thread.sleep(2000);
}
if lockingEnable) {
em.lock(customer, LockModeType.NONE);
}
}
Trang 8
@Override
public Customer getCustomer(String customerName) {
Predicate cond = null;
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Customer> cq = cb.createQuery(Customer.class);
Root<Customer> cust = cq.from(Customer.class);
cond = cb.like(cust.get(Customer_.customerName), "%" + customerName + "%");
cq.select(cust);
cq.where(cond);
TypedQuery<Customer> query = em.createQuery(cq);
return query.getResultList().get(0);
}
@Override
public void resetPoints(Customer customer) {
customer = em.getReference(Customer.class, customer.getId());
//Reset the points
customer.setRewardPts(1);
}
@Override
public void setLocking(boolean lockingEnable) {
this.lockingEnable = lockingEnable;
}
Step 6: Tạo các trang jsp ở ConcurrencyApp-war
ConcurrencyApp-war New Other Web JSP
CustomerForm.jsp
<%@ pagecontentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<metahttp-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Customer Form</title>
</head>
<body>
<h3>Customer Form</h3>
<divid="error" style="color: red"></div>
<formname="CustForm" method="POST" action="CustomerServlet">
<tablecolspan="2">
<tr><td>Customer Name:</td><td><inputtype="text" name="customerName"/></td></tr>
<tr><td>Reward Points:</td><td><inputtype="text" name="rewardPts"/></td></tr>
<tr><tdcolspan="2" align='center'><inputtype="submit" value="Submit"/></td></tr>
</table>
</form>
</body>
</html>
CustomerInfo.jsp
<%@ pagecontentType="text/html" pageEncoding="UTF-8"%>
Trang 9IT Research Department @BKAP 2015 Page 9 / 20
<!DOCTYPE html>
<html>
<head>
<metahttp-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Customer Search Page</title>
</head>
<body>
<formname="CustSearchForm" method="POST" action="CustomerSearchServlet">
<tablecolspan="2" width="60%">
<tr>
<td>Customer Name: </td>
<td><inputtype="text" size="20" name="customerName"/></td>
</tr>
<tr>
<tdcolspan="2" align="center"><inputtype="submit" value="Search"/></td>
</tr>
</table>
</form>
</body>
</html>
CustomerReward.jsp
<%@ pagecontentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<metahttp-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Customer Search</title>
</head>
<body>
<h3>Increment Reward Points</h3>
<formname="CustSearchForm" method="POST" action="CustomerReward">
<tablecolspan="2">
<tr>
<td>Customer Name:</td>
<td><inputtype="text" name="customerName"></td>
</tr>
<tr>
<td>Locking Enable:</td>
<td>
<selectname="locking">
<optionvalue="Yes">Yes</option>
<optionvalue="No">No</option>
</select>
</td>
</tr>
<tr>
<td>Add Times:</td>
<td><inputtype="text" name="add"></td>
</tr>
<tr>
<td>Multiply Times:</td>
Trang 10<td><inputtype="text" name="multiply"></td>
</tr>
<tr>
<tdcolspan="2" align="center"><inputtype="submit" value="Search"></td>
</tr>
</table>
</form>
</body>
</html>
CustomerReset.jsp
<%@ pagecontentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<metahttp-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Customer Search</title>
</head>
<body>
<h3>Customer Search</h3>
<formname="CustSearchForm" method="POST" action="CustomerReset">
<tablecolspan="2">
<tr>
<td>Customer Name:</td>
<td><inputtype="text" name="customerName"></td>
</tr>
<tr>
<tdcolspan="2" align="center"><inputtype="submit" value="Reset"/></td>
</tr>
</table>
</form>
</body>
</html>
Step 7: Tạo các Servlet
ConcurrencyApp-war Source Paclages New Other Web Servlet (package servlet)
CustomerInfo.java
package servlet;
import beanpack.RewardPtsModifyLocal;
import entity.Customer;
import java.io.IOException;
import java.io.PrintWriter;
import javax.ejb.EJB;
import javax.servlet.ServletException;
Trang 11IT Research Department @BKAP 2015 Page 11 / 20
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
*
* @author Quang
*/
public class CustomerInfo extends HttpServlet {
@EJB
private RewardPtsModifyLocal rewardPtsModify;
/**
* Processes requests for both HTTP <code>GET</code> and <code>POST</code>
* methods
*
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
String customerName = request.getParameter("customerName");
try (PrintWriter out = response.getWriter()) {
/* TODO output your page here You may use following sample code */
out.println("<!DOCTYPE html>");
out.println("<html>");
out.println("<head>");
out.println("<title>Servlet CustomerInfo</title>");
out.println("</head>");
out.println("<body>");
out.println("<table><tr><th>Customer Name</th><th>Reward Points</th></tr>");
out.println("<tr><td>" + customer.getCustomerName() + "</td><td>" + customer.getRewardPts() +
"</td></tr>");
out.println("</body>");
out.println("</html>");
}
}
// <editor-fold defaultstate="collapsed" desc="HttpServlet methods Click on the + sign on the left to edit the code.">
/**
* Handles the HTTP <code>GET</code> method
*
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {