JPA默认情况下和MyBatis一样开启一级缓存。JPA是针对与entityManager,Mybatis是针对于namespace。
同一个session可以使用缓存
@Autowired
EntityManager entityManager;
@Test
public void testSecondLevelCache(){
Customer customer1 = entityManager.find(Customer.class, 1);
Customer customer2 = entityManager.find(Customer.class, 1);
}
JPA的二级缓存是跨entityManager的,JPA的二级缓存需要显式配置。
事务提交后仍可以使用缓存
@Cacheable(true)//这里表示启用二级缓存
@Table(name="JPA_CUTOMERS")
@Entity
public class Customer {
//...
}
@Test
public void testSecondLevelCache(){
Customer customer1 = entityManager.find(Customer.class, 1);
transaction.commit();
entityManager.close();
entityManager = entityManagerFactory.createEntityManager();
transaction = entityManager.getTransaction();
transaction.begin();
Customer customer2 = entityManager.find(Customer.class, 1);
}
@EnableTransactionManagement
public class BioinfoApplication {
public static void main(String[] args) {
SpringApplication.run(BioinfoApplication.class, args);
}
}
@Service
public class RoleServiceImpl {
@Autowired
RoleRepository roleRepository;
void test{
roleRepository.findById(1);
roleRepository.findById(1);
Role role = entityManager.find(Role.class, 1);
Role role2 = entityManager.find(Role.class, 1);
}
}
事务不在service层处理
Hibernate: select role0_.id as id1_11_0_, role0_.en_name as en_name2_11_0_, role0_.name as name3_11_0_ from t_role role0_ where role0_.id=?
Hibernate: select role0_.id as id1_11_0_, role0_.en_name as en_name2_11_0_, role0_.name as name3_11_0_ from t_role role0_ where role0_.id=?
Hibernate: select role0_.id as id1_11_0_, role0_.en_name as en_name2_11_0_, role0_.name as name3_11_0_ from t_role role0_ where role0_.id=?
Hibernate: select role0_.id as id1_11_0_, role0_.en_name as en_name2_11_0_, role0_.name as name3_11_0_ from t_role role0_ where role0_.id=?
@Service
@Transactional
public class RoleServiceImpl {
@Autowired
RoleRepository roleRepository;
void test{
roleRepository.findById(1);
roleRepository.findById(1);
Role role = entityManager.find(Role.class, 1);
Role role2 = entityManager.find(Role.class, 1);
}
}
事务在service层处理,共享同一个session可以使用一级缓存
Hibernate: select role0_.id as id1_11_0_, role0_.en_name as en_name2_11_0_, role0_.name as name3_11_0_ from t_role role0_ where role0_.id=?
https://blog.csdn.net/fzy629442466/article/details/103458630
public class TransactionManagerConfig implements TransactionManagementConfigurer {
@Resource(name="txManager1")
private PlatformTransactionManager txManager1;
// 创建事务管理器1
@Bean(name = "txManager1")
public PlatformTransactionManager txManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
/** 没有引用spring-boot-starter-data-jpa 依赖
// 创建事务管理器2
@Bean(name = "txManager2")
public PlatformTransactionManager txManager2(EntityManagerFactory factory) {
return new JpaTransactionManager(factory);
}
*/
//其返回值代表在拥有多个事务管理器的情况下默认使用的事务管理
@Override
public PlatformTransactionManager annotationDrivenTransactionManager() {
return txManager1;
}
}
@Transactional(value="txManager1")
@Override
public User addUser(User user) {
userMapper.insert(user);
int i = 1 / 0;
return user;
}
import java.lang.annotation.*;
/**
* 注解类
*/
@Target(ElementType.METHOD) //定义注解用在方法上
@Retention(RetentionPolicy.RUNTIME) //运行时注解
@Documented
public @interface CustomTransaction {
String value() default "";
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Component;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.interceptor.DefaultTransactionAttribute;
@Component
@Scope(value = "prototype")
public class TransactionUtils {
@Autowired
private DataSourceTransactionManager dataSourceTransactionManager;
/**
*初始化创建TransactionStatus对象
* @return
*/
public TransactionStatus init(){
System.out.println("创建事务了...");
TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(new DefaultTransactionAttribute());
return transactionStatus;
}
/**
* 提交事务
* @param transactionStatus
*/
public void commit(TransactionStatus transactionStatus){
System.out.println("提交事务...");
dataSourceTransactionManager.commit(transactionStatus);
}
public void rollback(TransactionStatus transactionStatus){
System.out.println("事务回滚了....");
dataSourceTransactionManager.rollback(transactionStatus);
}
}
import io.tianma.common.annotation.CustomTransaction;
import io.tianma.common.utils.TransactionUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.TransactionStatus;
import java.lang.reflect.Method;
@Aspect
@Component
public class CustomTransactionAspect {
@Autowired
TransactionUtils transactionUtils;
/**
* 选择切面的注解CustomTransaction
*/
@Pointcut("@annotation(io.tianma.common.annotation.CustomTransaction)")
public void transactionPointCut() {
}
/**
* 方法增强@Arounbd
* @param point
*/
@Around("transactionPointCut()")
public void around(ProceedingJoinPoint point){
MethodSignature signature = (MethodSignature) point.getSignature();
Method method = signature.getMethod();//获取到方法对象
//获取到注解类
CustomTransaction annotation = method.getAnnotation(CustomTransaction.class);
if(annotation != null){
System.out.println(annotation.value());//打印注解上value的内容
}
//请求的类名以及方法名
String className = point.getTarget().getClass().getName();
String methodName = signature.getName();
System.out.println("执行的方法为:" + className + "." + methodName + "()");
//开启事务
TransactionStatus transactionStatus = transactionUtils.init();
try {
//执行方法
point.proceed();
//执行成功提交事务
transactionUtils.commit(transactionStatus);
} catch (Throwable throwable) {
//执行方法出错则回滚事务
transactionUtils.rollback(transactionStatus);
}
}
}
@Override
@CustomTransaction("新增用户开启事务")
public void saveUser() {
SysUserEntity user = new SysUserEntity();
user.setUserId("D123456");
user.setName("张三");
user.setCreateUserId("D123456");
user.setCreateTime(new Date());
this.save(user);
// System.out.println(1/0);
SysUserRoleEntity sysUserRoleEntity = new SysUserRoleEntity();
sysUserRoleEntity.setRoleId(123456L);
sysUserRoleEntity.setUserId("123456");
sysUserRoleService.save(sysUserRoleEntity);
}
List result = this.getResultFromQueryCache(session, queryParameters, querySpaces, resultTypes, queryCache, key);
if (result == null) {
result = this.doList(session, queryParameters, key.getResultTransformer());
this.putResultInQueryCache(session, queryParameters, resultTypes, queryCache, key, result);
}