=========================== MyBatis缓存机制之数据不一致 =========================== 每个服务(Service)都是独立的线程,各自持有独立的会话(SqlSession),而每个会话只负责维护自己的缓存。其中一个服务对数据库做了增删改操作,其它服务所持有会话中的缓存并不会因此失效。这就导致了数据不一致,即拿到的跟库里的不一样。 _______线程_______ _______线程_______ / \ / \ Service1 SqlSession Database SqlSession Service2 空 20 空 20 <- 20 <- 20 20 -> 20 -> 20 21 -> 空 -> 21 21 20 -> 20 \______ ______/ \ / 不一致 解决方案之一:所有服务(Service)共用同一个会话(SqlSession)。 public class MyBatisUtil { private static SqlSessionFactory factory; private static SqlSession session; // 饿汉单例 static { try { factory = new SqlSessionFactoryBuilder().build( Resources.getResourceAsStream("mybatis-config.xml")); } catch (IOException e) { e.printStackTrace(); } } public static SqlSessionFactory getFactory() { return factory; } public static SqlSession getSession() { return getSession(false); } public static void closeSession() { SqlSession session = local.get(); if (session != null) { session.close(); local.set(null); } } public static T getMapper(Class c) { return getSession(true).getMapper(c); } private static SqlSession getSession(boolean isAutoCommit) { if (session == null) session = factory.openSession(isAutoCommit); return session; } } 这样做的弊端是,如果有多个线程同时通过一个SqlSession操作数据库,可能引发冲突。 解决方案之二:每次查询后即清除缓存,迫使下一次查询读数据库。这样做的代价是牺牲了性能。