我试图理解为什么下面的代码片段不能像预期的那样工作。
我已经有id=1234和name=A1
的客户,我正在创建2个可调用的任务,并要求他们执行跨国更新
方法。
这两个事务一起运行(在从数据库中读取客户副本(如代码所示)后,我引入了1秒的延迟),并使用id=1234和name=A1读取原始客户
一个尝试从A1-更新
名称-
我期望至少有一个事务抛出提交冲突/陈旧的数据异常,但在下面的情况下,两个都成功了。
你能帮我理解一下吗?我在概念上遗漏了什么吗?
主要的JAVA
@Autowired
CustomerService service;
// Update address from A1 to A2
Callable<String> t1 = new Callable<String>() {
@Override
public String call() throws Exception {
service.updateCustomer("1234", "A2");
return "T1 Done";
}
};
// Update address from A1 to A3
Callable<String> t2 = new Callable<String>() {
@Override
public String call() throws Exception {
service.updateCustomer("1234", "A3");
return "T2 Done";
}
};
ExecutorService executorService = Executors.newFixedThreadPool(2);
executorService.invokeAll((Collection) Arrays.asList(t1, t2));
客户ervice.java
@Transactional
public void updateCustomer(String customerId, String customerName) {
try {
Optional<Customer> currentCopyHandle = repo.findById(customerId);
Customer currentCopy = currentCopyHandle.get();
Thread.sleep(1000);
ObjectMapper mapper = new ObjectMapper();
String customerDetails = currentCopy.getDetails();
ObjectNode writableDetails = (ObjectNode) mapper.readTree(customerDetails);
writableDetails.put("name", customerName);
currentCopy.setDetails(mapper.writeValueAsString(writableDetails));
repo.save(currentCopy);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
编辑-1客户。JAVA
这是一个与Oracle 12c兼容的POJO,其中名为
details
的字段标记为@Lob
,oracle12c表具有json约束
@Entity
public class Customer {
@Id
@javax.persistence.Id
private String cid;
@Lob
private String details;
public Customer() {
}
@PersistenceConstructor
public Customer(String cid, String details) {
super();
this.cid = cid;
this.details = details;
}
public String getCid() {
return cid;
}
public void setCid(String cid) {
this.cid = cid;
}
public String getDetails() {
return details;
}
public void setDetails(String details) {
this.details = details;
}
}
在我开始这个练习之前,我做了以下活动。
String json = "{ \"cid\" : \"1234\", \"name\" : \"A1\", \"address\" : \"India\"}";
service.saveCustomer1(new Customer("1234", json));
谢谢你JBNizet!
通过在我的模型中添加@Version属性来使用乐观锁定解决了我的问题。
我正在尝试使用线程池开发一个java聊天服务器,但我不知道如何处理来自客户端的传入消息。我想将每个套接字连接保存在哈希图中,并将任务添加到线程池的队列中。但是,服务器如何知道何时从客户端接收消息而不实例化缓冲区读取器?
本文向大家介绍JAVA 创建线程池的注意事项,包括了JAVA 创建线程池的注意事项的使用技巧和注意事项,需要的朋友参考一下 1、创建线程或线程池时请指定有意义的线程名称,方便出错时回溯。创建线程池的时候请使用带ThreadFactory的构造函数,并且提供自定义ThreadFactory实现或者使用第三方实现。 2、线程池不允许使用Executors去创建,而是通过ThreadPoolExecut
接收到数据时回调此函数,发生在worker进程中。函数原型: function onReceive(swoole_server $server, int $fd, int $reactor_id, string $data); $server,swoole_server对象 $fd,TCP客户端连接的唯一标识符 $reactor_id,TCP连接所在的Reactor线程ID $data,收到的数
主要内容:一、MySql中的线程,二、主要方式,三、源码流程,四、总结一、MySql中的线程 在mysql中,每一个连接上来,就会分配给一个相关的THD数据类。在前面的分析中可以看到,连接器(Connectors)连接到的直接就是连接池,在连接池的线程处理中分为三部分,即一对一(一个连接对应一个线程),多对一(多个连接对应一个线程)和线程池(多对多)。 线程池和线程可以针对不同的具体场景来处理具体的事务,这样既兼顾了效率又提高了适应性,对于新手来说,这就是设计的一个
本文向大家介绍jdk自带线程池实例详解,包括了jdk自带线程池实例详解的使用技巧和注意事项,需要的朋友参考一下 二、简介 多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力,但频繁的创建线程的开销是很大的,那么如何来减少这部分的开销了,那么就要考虑使用线程池了。线程池就是一个线程的容器,每次只执行额定数量的线程,线程池就是用来管理这些额定
主要内容:1 什么是Java 线程池,2 Java 线程池的优势,3 Java 线程池的应用场景,4 Java 线程池的例子1 什么是Java 线程池 Java线程池 表示一组正在等待作业并多次重复使用的工作线程。 如果是线程池,则会创建一组固定大小的线程。服务提供商从线程池中拉出一个线程并为其分配作业。作业完成后,线程再次包含在线程池中。 2 Java 线程池的优势 由于无需创建新线程,因此拥有更好的性能,可以节省时间。 3 Java 线程池的应用场景 在用户请求Servlet和JSP时,其中