详见我的架构之路中的文章: https://github.com/SevenPlusPlus/my_architecture_road/blob/master/chapter7.md
<dependency>
<groupId>com.miracle</groupId>
<artifactId>miracle-transaction-log</artifactId>
<version>1.0.0</version>
</dependency>
需要使用spring-boot
启动,底层mq使用了miracle-mq-starter
。另外,启动类需要设置扫描@com.miracle
,启用切面类。(使用传统aop:aspect
开启也是可以的,这对所有切面通用)
注解分为@ClassTransactional
和@LogTransactional
,@ClassTransactional
用作表示类下的所有方法开启事务埋点,@LogTransactional
则针对具体方法开启事务埋点。两个注解的配置属性一致,
@Component
@ClassTransactional(module="echoService")
public class CglibImpl {
@Autowired
private DsDao dsDao;
@LogTransactional(propagation=Propagation.PROPAGATION_SUPPORTS, module="remote")
public void updateUserInfo(UserInfo userInfo) {
dsDao.updateUserInfo(BeanUtils.beanToMap(userInfo));
}
public UserInfo getUserInfo(int userId) {
Map<String, Object> map = new HashMap<String, Object>();
map.put("userId", userId);
return dsDao.getUserInfo(map);
}
}
propagation表示事务传播属性,其值使用枚举类Propagation,含义与spring@Transactional
一致,默认使用PROPAGATION_REQUIRED
。module表示模块名称,埋点mq默认使用module+className+module来体现模块,类,方法。
类似spring事务,可以在spring-boot的application.properties设置方法事务属性管理。
miracle.transaction.attributes.set*=PROPAGATION_REQUIRED
miracle.transaction.attributes.get*=PROPAGATION_NEVER
根据方法名匹配Propagation,对于一个类,同时使用了@ClassTransactional和@LogTransactional,其事务传播属性使用优先级如下
@LogTransactional > attributes > @ClassTransactional
对于jdk动态代理生成的实现类,由于注解是无法被接口实现类继承,重写的方法也无法继承注解,aop是拦截不到的,例如mybatis mapper。对于以上情况,如果需要添加埋点,可以使用LogAopMaker
,让接口继承这个标记类,其所有的实现类,子类都能被aop所拦截。
import com.miracle.common.transaction.log.aop.LogAopMaker;
@ClassTransactional(module="mybatis")
public interface DsDao extends LogAopMaker{
public UserInfo getUserInfo(Map<String, Object> map);
public void updateUserInfo(Map<String, Object> map);
}
通过事务消费对账中心查看异常事务流水记录并人工干预解决