0%

JPA

  • parallelStream 调用 manyToMany 清除关联关系无效
1
2
3
4
5
6
7
8
9
10
11
12
@Transactional(readOnly = true)
public void clearAuthorBooks() {
List<Long> ids = new ArrayList<>(2);
ids.add(1L);
ids.add(2L);
ids.parallelStream().forEach(this::newTransaction);
}

@Transactional(propagation = Propagation.REQUIRES_NEW)
public void newTransaction(Long id) {
authorRepository.findById(id).ifPresent(author -> author.getBooks().clear());
}

这里使用基于注解的 Spring 事物,Spring 中大量使用基于代理的模式来处理方法调用,如果被代理对象实现了接口则使用 JDK 动态代理,未实现接口则使用 CGLIB 代理,通过代理在方法调用时获取注解进行事物处理,实际在方法处理中会使用 AOP 切面编程来处理不同切入点的事件,具体的两个实现类为 CglibAopProxyJdkDynamicAopProxy,切面的不同切入点 advice 又维护一系列的拦截方法 MethodInterceptor,通过方法调用时适合的拦截器会开始工作,比如我们这里的 TransactionInterceptor 会为方法调用包裹事物。

阅读全文 »

概述

Spring Boot Starters 是一系列为我们提供方便的依赖项描述符,通过在应用中加入这些依赖项描述符,我们就可以很方便的集齐所有需要的依赖和相关技术,不用再为解决依赖问题而浪费时间。比如你想使用 Spring 和 JPA 访问数据,在你的依赖管理文件中加入 spring-boot-starter-data-jpa 就好了,starter 就如它的名字一样 —— 快速启动。

官方的依赖一般遵循 spring-boot-starter-* 模式,* 为一种特定的技术或程序。详细的清单列表见链接

阅读全文 »

部分项目可能需要同时适配多种不同的数据库,比如常见的 Mysql、Oracle、Mssql 这几种数据库。首先我们准备测试数据库环境。

测试数据库准备

为了快速测试,我们使用 Docker 快速搭建数据库环境,对应的 Docker Compose 文件内容如下:

阅读全文 »

字符集、校对规则和 Unicode

字符集 (Character Sets) 是指一种从二进制编码到某类字符符号的映射,可以参考如何使用一个字节来表示英文字母。

“校对” (Collations) 是指一组用于某个字符集的排序规则。

MySQL 服务器有默认的字符集和校对规则,每个数据库也有自己的默认值,每个表也有自己的默认值。这是一个逐层继承的默认设置,最终最靠底层的默认设置将影响你创建的对象。这些默认值,至上而下地告诉 MySQL 应该使用什么字符集来存储某个列。

MySQL 8.0 默认服务端字符集和校对规则分别为 utf8mb4utf8mb4_0900_ai_ci

MySQL 5.6/5.7 默认服务端字符集和校对规则分别为 latin1latin1_swedish_ci

阅读全文 »

关于 JMSAMQP 在消息和代理上的一些说明。

如今,AMQP 越来越受欢迎。因此,我认为这是一个很好的机会,以了解它如何与旧的 JMS 匹配。


JMS

包括 Java RMI 在内的远程过程调用(RPC)系统基本都是是同步的 – 调用者必须阻塞并等待,直到被调用的方法完成执行,因此,如果不使用多个线程,则无法开发松耦合的企业应用程序。换句话说,RPC 系统要求客户端和服务器同时可用。然而,在某些应用中,这种紧密耦合可能是不可能的或奢望的。面向消息的中间件 - Message Oriented Middleware(MOM)系统为此类问题提供了解决方案。它们基于异步交互模型,并提供可通过网络访问的消息队列的抽象。

阅读全文 »

概述

MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects)为数据库中的记录。

MyBatis 作为一款持久层框架,它趋向于以数据库为中心,因此主要的关注点会落在 SQL 定义、结果映射上,相对来说比较轻量,也更容易入手,对于 SQL 优化也比较容易,但也正是由于偏重 SQL,将会和使用的数据库强关联。

对比 ORM 框架

同时使用面向对象的软件和关系数据库既麻烦又费时。由于对象和关系数据库中的数据表示方式之间存在范式不匹配,因此开发成本要高得多。

相比 ORM 框架,ORM 框架更多的将关注点放在面向对象的域模型和业务逻辑层,ORM 框架一般会遵循 JPA 标准,比如最常见的实现 Hibernate

ORM 框架的主要目的之一是降低与特定数据库的耦合性,它抽象了数据库系统,因此在不同数据库切换、移植时会更加容易,抽象的代价是与之而来的复杂性的增加,但也提供了更多丰富的功能特性:数据变更追踪、审计、一/二级缓存、并发版本控制、数据懒加载、级联操作,以及丰富的查询方式:SQLHQLJPQLCriteria APIQuery DSL 等;

阅读全文 »

线程安全性

要编写线程安全的代码,其核心在于要对状态访问操作进行管理,特别是对共享的(Shared)和可变(Mutable)的状态的访问。

对象的状态是指存储在状态变量(例如实例或静态域)中的数据。对象的状态可能包含其他依赖对象的域。

如果当多个线程访问同一个可变的状态变量时没有使用合适的同步,那么程序就会出现错误。有三种方式可以修复这个问题:

  • 不在线程之间共享该状态变量
  • 该状态变量修改为不可变的变量
  • 在访问状态变量时使用同步
阅读全文 »

历史

在早些的文献中,共识(consensus)也叫做协商(agreement)。

本文按照最有意义的顺序进行讨论,而不是按照发表的顺序。

我所知道的共识问题的第一个实例是在 Lamport 的 “Time, Clocks and the Ordering of Events in a Distributed System” (1978) 中,尽管它没有明确声明为共识或协商问题。在本文中,Lamport 讨论了消息如何在处理器之间以有限的时间传播,并与爱因斯坦的狭义相对论进行了类比。并给出了一个完整的分析,包括时空图等等。问题在于,在分布式系统中,您无法判断事件 A 是否发生在事件 B 之前,除非 A 以某种方式导致了 B。每个观察者都可以看到事件以不同的顺序发生,除了相互导致的事件,即在分布式系统中事件只有部分有序。Lamport 定义了“happens before”的关系和运算符,并继续提供一种算法,该算法提供分布式系统中事件的总排序,以便每个进程以与其他进程相同的顺序查看事件。

阅读全文 »

索引是存储引擎用于快速找到记录的一种数据结构。这是索引的基本功能。
索引对于良好的性能非常关键。尤其是当表中的数据量越来越大时,索引对性能的影响愈发重要。在数据量较小且负载较低时,不恰当的索引对性能的影响可能还不明显,但当数据量逐渐增大时,性能则会急剧下降。

阅读全文 »

1. 引言

Java 的核心优势之一是借助 JVM 内置的垃圾收集器(或简称 GC)的自动内存管理。GC 隐式地负责分配和释放内存,因此能够处理大多数内存泄漏问题。

尽管 GC 有效地处理了很大一部分内存,但它不能保证针对内存泄漏的万无一失的解决方案。 GC 非常聪明,但并非完美无缺。即使在有责任心的开发人员的应用程序中,内存泄漏仍然可能存在。

在某些情况下,应用程序会生成大量多余的对象,从而耗尽关键的内存资源,有时会导致整个应用程序的故障。

内存泄漏是 Java 中的真正问题。在本教程中,我们将看到导致内存泄漏的潜在原因是什么,如何在运行时识别它们,以及如何在应用程序中对其进行处理。

阅读全文 »