先看两块代码,他们达到的效果是一样的,两个问题:
1. 为什么要第二种?(这个看个别业务场景,有些mapper比如日志,业务出错了也不需要回滚,看注释代码逻辑和解释)
2. 第一种自定义事务注解,怎么写的?(继续看下面)
@CrmRedisTransactional
public boolean updateByPrimaryKeySelective(SystemParameterInfo systemParameterInfo) {
return systemParameterInfoMapper.updateByPrimaryKeySelective(systemParameterInfo)>0?true:false;
}
@Override
public boolean updateFordelete(SystemParameterInfo systemParameterInfo) {
//return systemParameterInfoMapper.updateByPrimaryKeySelective(systemParameterInfo)>0?true:false;
int i = 0;
TransactionStatus transactionStatus = null;
try {//自己手动控制事务管理
transactionStatus = noAutoTransactionalUtil.begin();
i = systemParameterInfoMapper.updateByPrimaryKeySelective(systemParameterInfo);
noAutoTransactionalUtil.commit(transactionStatus);
}catch (Exception e){
if(noAutoTransactionalUtil != null){
noAutoTransactionalUtil.rollback(transactionStatus);
}
return false;
}
//如果下面这里可以写另外的mapper操作,这里的操作,就没事务了
//commonLogInfoMapper.insertLog();
return i == 1?true:false;
}
第二个问题,怎么写自定义事务管理器:
自定义事务管理器:
//自定义事务管理器
import java.lang.annotation.*;
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface CrmRedisTransactional {
}
AOP类:
//必须在spring的配置文件 加入:<aop:aspectj-autoproxy proxy-target-class="true"/> 否则这里代码不生效
@Component
@Slf4j
@Aspect
public class CrmRedisTransactionalAop {
@Autowired
private NoAutoTransactionalUtil noAutoTransactionalUtil;
@Around(value = "@annotation(com.zhiguan.carownerhomecrm.transactional.CrmRedisTransactional)")
public Object around(ProceedingJoinPoint joinPoint){
TransactionStatus begin = null;
try {
begin = noAutoTransactionalUtil.begin();
Object result = joinPoint.proceed();//目标方法
noAutoTransactionalUtil.commit(begin);
return result;
} catch (Throwable e) {
e.printStackTrace();
if(begin != null){
noAutoTransactionalUtil.rollback(begin);
//业务场景:正常业务回滚,但是下面有些这种统一日志都不需要回滚的
// 记录日志systemParameterInfoService.insertlog();
}
return "系统异常";
}
}
}
事务管理器的工具类:
//编程事务,自定义,自己控制 begin commit rollback
//缺点,代码繁杂,优点:扩展性更强,自己控制什么时候commit 和rollback
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Component;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.interceptor.DefaultTransactionAttribute;
@Component
public class NoAutoTransactionalUtil {
@Autowired
private DataSourceTransactionManager dataSourceTransactionManager;
/**
* 开启事务
* @return
*/
public TransactionStatus begin(){
TransactionStatus transaction = dataSourceTransactionManager.getTransaction(new DefaultTransactionAttribute());
return transaction;
}
/**
* 提交事务
* @return
*/
public void commit(TransactionStatus transactionStatus){
dataSourceTransactionManager.commit(transactionStatus);
}
/**
* 回滚事务
* @return
*/
public void rollback(TransactionStatus transactionStatus){
dataSourceTransactionManager.rollback(transactionStatus);
}
}