JPA Hibernate 框架中的实体entity有三种状态,transient(瞬时状态),persistent(持久化状态)以及detached(离线状态)自动持久化,本文主要是讨论持久化状态的一些细节问题。
如果一个实体entity通过query语句查出来后,调用实体相关的setXXX方法,有可能会被待久化到db中,也有可以不会,总体来说,关键点取决于setXXX方法所处的函数是否有事务(Session)包裹着,但到生产环境中,会有比较多的复杂情况,下面我们以声明式事务的实现方式来探讨,编程式事务主要就是手工对session和transaction的管理,与之类似,亦可借鉴。
1、单一业务,自动提交场景(主方法test有事务):
@Service public class FunctionService { private Logger logger = LoggerFactory.getLogger(FunctionService.class); @Autowired private TUserServcie tUserServcie; @Autowired private TAddressServcie tAddressServcie; //测试方法 @Transactional() public void test(String name){ TUser user = tUserServcie.findByName(name); logger.info("test before age:"+user.getAge()); user.setAge(user.getAge()+1); } } 复制代码
2、单一业务,不会自动提交场景(主方法test不含事务事务或为read-only):
@Service public class FunctionService { private Logger logger = LoggerFactory.getLogger(FunctionService.class); @Autowired private TUserServcie tUserServcie; @Autowired private TAddressServcie tAddressServcie; //测试方法 //@Transactional(readOnly = true) public void test(String name){ TUser user = tUserServcie.findByName(name); logger.info("test before age:"+user.getAge()); user.setAge(user.getAge()+1); } } 复制代码
3、复合业务,不会自动提交(test无事务或read-only且countAllNotTrans无事务或read-only)
@Service public class FunctionService { private Logger logger = LoggerFactory.getLogger(FunctionService.class); @Autowired private TUserServcie tUserServcie; @Autowired private TAddressServcie tAddressServcie; //测试方法 //@Transactional(readOnly = true) public void test(String name){ TUser user = tUserServcie.findByName(name); logger.info("test before age:"+user.getAge()); user.setAge(user.getAge()+1); tAddressServcie.countAll(); } } @Service public class TAddressServcie { @Autowired private TAddressRepo tAddressRepo; //@Transactional(readOnly = true) public int countAll (){ return tAddressRepo.countAll(); } } public interface TAddressRepo extends JpaRepository<TAddress, Integer> { @Query(value ="SELECT count(*) FROM TAddress") int countAll(); } 复制代码
4、特别注意!!!复合业务,会自动提交(test无事务,countAll有事务)
@Service public class FunctionService { private Logger logger = LoggerFactory.getLogger(FunctionService.class); @Autowired private TUserServcie tUserServcie; @Autowired private TAddressServcie tAddressServcie; //测试方法 public void test(String name){ TUser user = tUserServcie.findByName(name); logger.info("test before age:"+user.getAge()); user.setAge(user.getAge()+1); tAddressServcie.countAll(); } } @Service public class TAddressServcie { @Autowired private TAddressRepo tAddressRepo; @Transactional() public int countAll (){ return tAddressRepo.countAll(); } } public interface TAddressRepo extends JpaRepository<TAddress, Integer> { @Query(value ="SELECT count(*) FROM TAddress") int countAll(); } 复制代码