spring源码学习之整合Mybatis之后事物执行

        前面记录了一片《spring源码学习之整合Mybatis原理分析》之后,这篇记录spring在整合mybatis之后,目标方法的调用过程和事物的管理。

        通过这篇文章分析之后,至少需要解决本人关注的两个问题:

  1. 调用mapper方法的执行过程是怎样的?
  2. mybatis的事物和spring的事物是如何被管理的?

        配置文件还是遵从前面文章的记录,测试用例如下:

public static void main(String[] args){
        ApplicationContext ctx = new ClassPathXmlApplicationContext("bean.xml");
        IAuthUserService authUserServiceImpl = ctx.getBean(AuthUserServiceImpl.class);
        AuthUser authUser = new AuthUser();
        authUser.setId((long) 4);
        int ret = authUserServiceImpl.delete(authUser);
        logger.info("执行结果:"+ ret);
    }

        delete的实现也很简单,用户的软删除,根据主键去更新用户表的is_delete字段的值为0:

@Service
public class AuthUserServiceImpl implements IAuthUserService {

	private static Logger logger = Logger.getLogger(AuthUserServiceImpl.class);

	@Autowired
	private AuthUserMapper authUserMapper;

	@Override
	public int delete(AuthUser authUser) {
		if(authUser == null){
			return 0;
		}
		authUser.setIsDelete((byte) 0);
		authUser.setUpdateTime(new Date());
		return authUserMapper.updateByPrimaryKeySelective(authUser);
	}
}

目标方法执行过程

        这篇文章中《spring源码学习之整合Mybatis原理分析》记录了,authUserMapper变量指向的实例,实际上是一个代理类,程序在调用authUserMapper对象的某个方法的时候,就会调用到MapperProxy对象的invoke()方法。接下来就分析这个MapperProxy的invoke()方法。

        先贴一张时序图,以后有时间了,在来详细记录,感觉mybatis里面的东西写得挺乱的。

spring源码学习之整合Mybatis之后事物执行_第1张图片        大概的过程分为下面几步:

  1. 创建一个DefaultSqlSession,并将这个DefaultSqlSession和DefaultSqlSessionFactory做一个绑定,记录在spring-tx的TransactionSynchronizatioManager事物管理器中。
  2. 创建一个SqlSessionUtils.SqlSessionSynchronization对象,将这个对象注册到TransactionSynchronizatioManager事物管理器中,这个对象在事物提交阶段会用到。
  3. 获取一个connection,这个连接是从SpringManagedTransaction中获取的,但是实际上也是根据dataSource间接从spring中的TransactionSynchronizatioManager事物管理器中获取的,事物管理器中的这个connection是在spring创建事物的时候创建的,并且connection和dataSource做了一个ThreadLocal绑定。
  4. 执行prepareStatement,创建JDBC42PreparedStatement,这个类是mysql-connector包中的对象,不再属于mybatis包。
  5. 设置参数,替换sql中的占位符“?”。
  6. 调用JDBC42PreparedStatement的excute方法,执行sql脚本。
  7. 处理返回结果。

        浓缩之后,就是上面这些步骤,创建了太多的类,有些类有些泛滥了,没感觉有多大的作用。

事物提交

        从上面的时序图可以看得出来,mybatis并没有创建自己的事物管理器,创建了一个SpringManagedTransaction管理器,是在mybatis-spring包中的,而这个事物管理器也是委托spring在管理事物。具体来讲,执行目标方法的过程中,需要创建一个connection连接,这个连接是通过SpringManagedTransaction事物管理器,最终从spring的TransactionSynchronizatioManager事物管理器中获取的。

        再看看执行完目标方法之后,及数据库的操作之后,事物的提交或者回滚在哪儿完成的。上时序图:

spring源码学习之整合Mybatis之后事物执行_第2张图片        执行完目标方法之后,程序返回到TransactionInterceptor,这个拦截器定义了事物的框架,

  1. 首先开启创建事物。
  2. 执行目标方法,进行数据库操作。
  3. 提交事物或者回滚。
  4. 清理缓存或者临时变量。
  5. 释放连接connection,连接返回到连接池。 

        spring事务管理器对外提供了回调接口,这个回调接口允许外部程序可以在事物提交之前和提交之后,做一些事情。mybatis的SqlSessionUtils.SqlSessionSynchronization就实现了这些接口。SqlSessionSynchronization这个是什么时候注册到spring的事物管理器里的呢?答案就是上面的时序图中。
spring源码学习之整合Mybatis之后事物执行_第3张图片

        先记录这些吧,等以后有充足时间了,在详细分析,这儿先描述轮廓。再贴一张类图:

spring源码学习之整合Mybatis之后事物执行_第4张图片

 

 

 

 

 

 

 

你可能感兴趣的:(spring)