运行 具有特定条件和时间的线程
Run Thread with specific condition and time
我想创建一个条件,当用户下订单时,有一个线程 运行s 持续 20 秒以检查数据库付款状态是完成还是待处理,如果完成则线程将停止,如果它仍然挂起那么线程将继续 运行 20 秒并更新数据库中的状态被取消,我正在使用 mybatis 和 XML mapper
here is my code
public class PaymentCheck implements Runnable{
private String username;
public PaymentCheck(String username) {
this.username = username;
}
@Override
public void run() {
SqlSession session = MyBatisUtil.getSqlSessionFactory().openSession();
Booking bookStatus = session.selectOne("User.check",username);
String status = bookStatus.getPayment_status();
while (status.equalsIgnoreCase("pending")){
final Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
int i = 6; // Time in seconds
public void run() {
System.out.println(i--);
if (i < 0) {
timer.cancel();
}
}
}, 0, 1000);
}
}
}
here is my code in controller
@RequestMapping(value = "/Booking", method = RequestMethod.POST,consumes = "application/json", produces = "application/json")
public ResponseEntity<?> Booking(@RequestBody JSONObject jobj, @RequestHeader(HEADER) String header) throws RestClientException, JsonProcessingException {
String username = userRepo.claimToken(SECRET,PREFIX,header);
jobj.put("username",username);
HttpHeaders headers = new HttpHeaders();
MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
headers.setContentType(type);
System.out.println(jobj.toString());
HttpEntity<JSONObject> formEntity = new HttpEntity<JSONObject>(jobj, headers);
JSONObject json = restTemplate.postForEntity("http://localhost:8080/hotel/Booking", formEntity, JSONObject.class).getBody();
String message = String.valueOf(json.get("Booking Status"));
if (!message.equalsIgnoreCase("Failed")) {
System.out.println("json:" + json.toString());
System.out.println(username);
PaymentCheck tq = new PaymentCheck(username);
tq.run();
return new ResponseEntity<>(json,HttpStatus.CREATED);
}else{
return new ResponseEntity<>(json,HttpStatus.CREATED);
}
}
这是数据库
它没有显示任何错误,但也没有改变任何东西...
你似乎把这个复杂化了。
问题 1:您的线程每秒轮询一次,但控制器响应不会等待更新发生才响应客户。所以投票没有意义。
问题 2:您的线程实际上并未更新数据库。
解决方案:
- 在主线程中执行检查,轮询然后响应。
- 设置一个定时任务,在未来20秒后执行一次单次执行更新
使用通用 JDBC.
的解决方案 2 的示例代码
private Timer timer = new Timer();
@RequestMapping(value = "/Booking", method = RequestMethod.POST,consumes = "application/json", produces = "application/json")
public ResponseEntity<?> Booking(@RequestBody JSONObject jobj, @RequestHeader(HEADER) String header) throws RestClientException, JsonProcessingException {
String username = userRepo.claimToken(SECRET,PREFIX,header);
jobj.put("username",username);
HttpHeaders headers = new HttpHeaders();
MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
headers.setContentType(type);
System.out.println(jobj.toString());
HttpEntity<JSONObject> formEntity = new HttpEntity<JSONObject>(jobj, headers);
JSONObject json = restTemplate.postForEntity("http://localhost:8080/hotel/Booking", formEntity, JSONObject.class).getBody();
String message = String.valueOf(json.get("Booking Status"));
if (!message.equalsIgnoreCase("Failed")) {
System.out.println("json:" + json.toString());
System.out.println(username);
TimerTask tt = new PaymentCheck(username);
timer.schedule(tt, 20000);
return new ResponseEntity<>(json,HttpStatus.CREATED);
}else{
return new ResponseEntity<>(json,HttpStatus.CREATED);
}
}
public class PaymentCheck extends TimerTask {
private static final MYQUERY = "update User.check set payment_status = 'cancelled' where payment_status = 'pending' and user = ?";
private String username;
public PaymentCheck(String username) {
this.username = username;
}
@Override
public void run() {
try (Connection cn = ...) {
try (Statement stmt = new PreparedStatement(MYQUERY))
{
stmt.setString(1, username);
stmt.execute();
cn.commit();
}
}
}
}
我想创建一个条件,当用户下订单时,有一个线程 运行s 持续 20 秒以检查数据库付款状态是完成还是待处理,如果完成则线程将停止,如果它仍然挂起那么线程将继续 运行 20 秒并更新数据库中的状态被取消,我正在使用 mybatis 和 XML mapper
here is my code
public class PaymentCheck implements Runnable{
private String username;
public PaymentCheck(String username) {
this.username = username;
}
@Override
public void run() {
SqlSession session = MyBatisUtil.getSqlSessionFactory().openSession();
Booking bookStatus = session.selectOne("User.check",username);
String status = bookStatus.getPayment_status();
while (status.equalsIgnoreCase("pending")){
final Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
int i = 6; // Time in seconds
public void run() {
System.out.println(i--);
if (i < 0) {
timer.cancel();
}
}
}, 0, 1000);
}
}
}
here is my code in controller
@RequestMapping(value = "/Booking", method = RequestMethod.POST,consumes = "application/json", produces = "application/json")
public ResponseEntity<?> Booking(@RequestBody JSONObject jobj, @RequestHeader(HEADER) String header) throws RestClientException, JsonProcessingException {
String username = userRepo.claimToken(SECRET,PREFIX,header);
jobj.put("username",username);
HttpHeaders headers = new HttpHeaders();
MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
headers.setContentType(type);
System.out.println(jobj.toString());
HttpEntity<JSONObject> formEntity = new HttpEntity<JSONObject>(jobj, headers);
JSONObject json = restTemplate.postForEntity("http://localhost:8080/hotel/Booking", formEntity, JSONObject.class).getBody();
String message = String.valueOf(json.get("Booking Status"));
if (!message.equalsIgnoreCase("Failed")) {
System.out.println("json:" + json.toString());
System.out.println(username);
PaymentCheck tq = new PaymentCheck(username);
tq.run();
return new ResponseEntity<>(json,HttpStatus.CREATED);
}else{
return new ResponseEntity<>(json,HttpStatus.CREATED);
}
}
这是数据库
它没有显示任何错误,但也没有改变任何东西...
你似乎把这个复杂化了。
问题 1:您的线程每秒轮询一次,但控制器响应不会等待更新发生才响应客户。所以投票没有意义。
问题 2:您的线程实际上并未更新数据库。
解决方案:
- 在主线程中执行检查,轮询然后响应。
- 设置一个定时任务,在未来20秒后执行一次单次执行更新
使用通用 JDBC.
的解决方案 2 的示例代码private Timer timer = new Timer();
@RequestMapping(value = "/Booking", method = RequestMethod.POST,consumes = "application/json", produces = "application/json")
public ResponseEntity<?> Booking(@RequestBody JSONObject jobj, @RequestHeader(HEADER) String header) throws RestClientException, JsonProcessingException {
String username = userRepo.claimToken(SECRET,PREFIX,header);
jobj.put("username",username);
HttpHeaders headers = new HttpHeaders();
MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
headers.setContentType(type);
System.out.println(jobj.toString());
HttpEntity<JSONObject> formEntity = new HttpEntity<JSONObject>(jobj, headers);
JSONObject json = restTemplate.postForEntity("http://localhost:8080/hotel/Booking", formEntity, JSONObject.class).getBody();
String message = String.valueOf(json.get("Booking Status"));
if (!message.equalsIgnoreCase("Failed")) {
System.out.println("json:" + json.toString());
System.out.println(username);
TimerTask tt = new PaymentCheck(username);
timer.schedule(tt, 20000);
return new ResponseEntity<>(json,HttpStatus.CREATED);
}else{
return new ResponseEntity<>(json,HttpStatus.CREATED);
}
}
public class PaymentCheck extends TimerTask {
private static final MYQUERY = "update User.check set payment_status = 'cancelled' where payment_status = 'pending' and user = ?";
private String username;
public PaymentCheck(String username) {
this.username = username;
}
@Override
public void run() {
try (Connection cn = ...) {
try (Statement stmt = new PreparedStatement(MYQUERY))
{
stmt.setString(1, username);
stmt.execute();
cn.commit();
}
}
}
}