Java for Web学习笔记(一零四):Spring框架中使用JPA(4)Service中使用事务

Spring和JTA的@Transactional标记

总体而言,Spring的@Transactional比JTA的@Transactional要强大和更灵活。

@javax.transaction.Transactional,可以配置参数:

  • dontRollbackOn:不触发回滚的异常黑名单
  • roolbackOn:异常白名单将覆盖缺省的rollback规则
  • value:什么时候和如何创建transaction,值为Transactional.TxType的enum,如下,缺省为REQUIRED。
    • MANDATORY:transaction必须存在,不会创建新的,如果没有,抛出异常
    • NEVER:transaction必须不存在,否则抛出异常
    • NOT_SUPPORTED:transaction没有被使用,如果已经存在,将被挂起,代码在事务外运行,完成后,事务继续。
    • REQUIRED:transaction必须被使用,如果不存在,将在方法前开始创建,并在方法返回时结束。如果已经存在,则是使用之。
    • REQUIRES_NEW:如果不存在,将在方法前开始,并在方法返回时结束,如果存在,则原transaction被挂起,开启新的transaction,并在方法结束是,结束新的transaction,继续执行原事务。
    • SUPPORTS:如果已经有transaction,则使用之,如果没有,则不使用事务执行代码。

@org.springframework.transaction.annotation.Transactional使用:

  • noRollbackFor 等同@javax.transaction.Transactional的dontRollbackOn
  • rollbackFor 等同@javax.transaction.Transactional的rollbackOn
  • propagation 等同@javax.transaction.Transactional的value,enum同Transactional.TxType的enum,缺省值都是REQUIRED。此外增加了
    • NESTED:如果不存在,创建一个新的事务,如果存在,创建一个nested事务。JpaTransactionManager不支持NESTED,只被某些JpaTransactionManager提供者提供的JpaTransactionManager所支持,因此不具有可移植性。
  • noRollbackForClassName
  • rollbackForClassName
  • isolation:设置isolation等级,使用org.springframework.transaction.annotation.Isolation enum,有NONE, READ_COMMITTED, READ_UNCOMMITTED,REPEATABLE_READ和SERIALIZABLE,如无特殊,我们可以使用READ_COMMITTED。但是JpaTransactionManager和JtaTransactionManager都不支持对事务的isolation等级,会忽略该参数,它们将采用JPA或者JTA DataSource的isolation等级,如果没有,则使用JDBC的限制等级。
  • readOnly:但JpaTransactionManager和JtaTransactionManager均不支持,不允许写。
  • timeout:JtaTransactionManager,但JpaTransactionManager不支持,限定transaction的执行时间(不含rollback)。

@Transactional可以标记接口或其方法,类或其方法。建议标记在类获取方法。如果标记在接口,只有允许动态proxy(即proxyTargetClass = false)时才有效。而且事务应是具体实现,而不是在接口契约的限制(和validate不同)

Service中使用事务的小例子

@Service
public class DefaultBookManager implements BookManager {
	@Inject AuthorRepository authorRepository;
	@Inject BookRepository bookRepository;
	@Inject PublisherRepository publisherRepository;
	
	/*【注意】如果我们不标记为@Transactional,在写操作中会出现nested exception is javax.persistence.
         * TransactionRequiredException: No EntityManager with actual transaction available for current thread - 
         * cannot reliably process 'persist' call的异常。这是获取EntityManager出错,获取是从SharedEntityManagerBean
         *中获得,可能和isolation的等级有关。纯读的操作没有问题。*/
	@Override
	@Transactional
	public List getAuthors() {
		return this.toList(authorRepository.getAll());
		
	}

	@Override
	@Transactional
	public void saveAuthor(Author author) {
		if(author.getId() < 1)
			this.authorRepository.add(author);
		else
			this.authorRepository.update(author);
		
	}
	......      
}

相关链接: 我的Professional Java for Web Applications相关文章

你可能感兴趣的:(JAVA,读书笔记,愷风(Wei)之Java,for,Web学习笔记)