每天叫醒你的不是闹钟,而是梦想
4
Spring Data JPA的事务支持
Spring Data JPA对所有的默认方法都开启了事务支持,且查询事务默认启用readOnly = true属性(指定当前事务是只读事务)
我们通过查看SimpleJpaRepository的部分源码,来查看Spring Data JPA的事务支持
@Repository
@Transactional(
readOnly = true
)
public class SimpleJpaRepository<T, ID> implements JpaRepositoryImplementation<T, ID> {
@Transactional
public void delete(T entity) {
Assert.notNull(entity, "The entity must not be null!");
this.em.remove(this.em.contains(entity) ? entity : this.em.merge(entity));
}
@Transactional
public void deleteAll(Iterable<? extends T> entities){
Assert.notNull(entities, "The given Iterable of entities not be null!");
Iterator var2 = entities.iterator();
while(var2.hasNext()) {
T entity = var2.next();
this.delete(entity);
}
}
@Transactional
public void deleteInBatch(Iterable<T> entities) {
Assert.notNull(entities, "The given Iterable of entities not be null!");
if (entities.iterator().hasNext()) {
QueryUtils.applyAndBind(QueryUtils.getQueryString("delete from %s x", this.entityInformation.getEntityName()), entities, this.em).executeUpdate();
}
}
@Transactional
public void deleteAll() {
Iterator var1 = this.findAll().iterator();
while(var1.hasNext()) {
T element = var1.next();
this.delete(element);
}
}
public T getOne(ID id) {
Assert.notNull(id, "The given id must not be null!");
return this.em.getReference(this.getDomainClass(), id);
}
public List<T> findAll() {
return this.getQuery((Specification)null, (Sort)Sort.unsorted()).getResultList();
}
public List<T> findAll(Sort sort) {
return this.getQuery((Specification)null, (Sort)sort).getResultList();
}
public Page<T> findAll(Pageable pageable) {
return (Page)(isUnpaged(pageable) ? new PageImpl(this.findAll()) : this.findAll((Specification)null, pageable));
}
@Transactional
public <S extends T> S save(S entity) {
if (this.entityInformation.isNew(entity)) {
this.em.persist(entity);
return entity;
} else {
return this.em.merge(entity);
}
}
@Transactional
public <S extends T> S saveAndFlush(S entity) {
S result = this.save(entity);
this.flush();
return result;
}
@Transactional
public <S extends T> List<S> saveAll(Iterable<S> entities) {
Assert.notNull(entities, "The given Iterable of entities not be null!");
List<S> result = new ArrayList();
Iterator var3 = entities.iterator();
while(var3.hasNext()) {
S entity = var3.next();
result.add(this.save(entity));
}
return result;
}
@Transactional
public void flush() {
this.em.flush();
}
}
从源码中我们可以看出, SimpleJpaRepository在类级别定义了@Transactional(readOnly = true), 而在和save、delete相关的操作重写了@Transactional属性,此时readOnly属性是false,其余查询操作readOnly仍然为true
注意:@Transactional不仅可以注解在方法上, 也可以注解在类。当注解在类上的时候意味着此类的所有public方法都是开启事务的。如果类级别和方法级别同时使用了@Transactional注解,则使用方法级别覆盖类级别注解
readOnly的默认值为false
5
Spring Data JPA事务回滚实例
package com.zero.ch8_2.service.impl;
import com.zero.ch8_2.dao.PersonRepository;
import com.zero.ch8_2.domain.Person;
import com.zero.ch8_2.service.PersonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
/**
* @Author: Zero
* @Date: 2019/4/15 22:33
*/
public class PersonServiceImpl implements PersonService {
@Autowired
PersonRepository personRepository;
@Override
@Transactional(rollbackFor = {IllegalArgumentException.class}) //rollbackFor属性,指定特定异常时,数据回滚
public Person savePersonWithRollBack(Person person) {
Person p = personRepository.save(person);
if(person.getName() .equals("zero")){
throw new IllegalArgumentException("zero already exist,data will rollback");
}
return p;
}
@Override
@Transactional(noRollbackFor = {IllegalArgumentException.class}) noRollbackFor属性,指定特定异常时,数据不回滚
public Person savePersonWithoutRollBack(Person person) {
Person p = personRepository.save(person);
if(person.getName() .equals("zero")){
throw new IllegalArgumentException("zero already exist,data will not rollback");
}
return p;
}
}
6
数据缓存 Cache
6.1 什么是缓存
我们知道一个程序的瓶颈在于数据库, 我们也知道内存的速度是大大快于硬盘的速度的。 当我们需要重复地获取相同的数据的时候,我们一次又一次的请求数据库, 导致大量的时间耗费在数据库查询方法的调用上,导致程序性能的恶化,这便是数据缓存要解决的问题。
6.2声名式缓存注解
@Cacheble : 在方法执行前Spring先查看缓存中是否有数据, 如果有数据,则直接返回缓存数据;若没有数据,调用方法并将方法返回值放进缓存
@CachePut : 无论怎样,都会将方法的返回值放到缓存中。 @CachePut的属性与@Cacheable保持一致。
@CacheEvict : 将一条或多条数据从缓存中删除。
@Caching : 可以通过@Caching注解组合多个注解策略在一个方法上。
首先在启动类中添加缓存注解
package com.zero.ch8_2;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
@SpringBootApplication
@EnableCaching
public class Ch82Application {
public static void main(String[] args) {
SpringApplication.run(Ch82Application.class, args);
}
}
package com.zero.ch8_2.service.impl;
import com.zero.ch8_2.dao.PersonRepository;
import com.zero.ch8_2.domain.Person;
import com.zero.ch8_2.service.CacheService;
import org.hibernate.annotations.Cache;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
/**
* @Author: Zero
* @Date: 2019/4/15 23:58
*/
public class CacheServiceImpl implements CacheService {
@Autowired
PersonRepository personRepository;
@Override
@CachePut(value = "people", key = "#person.id")
// 缓存新增的或更新的数据到缓存, 其中缓存名称为people, 数据的key是person的id
public Person save(Person person) {
Person p = personRepository.save(person);
return p;
}
@Override
@CacheEvict(value = "people")
// @CacheEvict从缓存people中删除key为id的数据
public void remove(Long id) {
personRepository.delete(id);
}
@Override
@Cacheable(value = "people", key = "#people.id")
// @Cacheable缓存key为person的id数据到缓存people中
public Person findOne(Person person) {
Person p = personRepository.findOne(person.getId());
return p;
}
}
历史文章
点击蓝字关注我们