1、事物属性
事物属性主要是通过TransactionDefinition接口实现定义,主要有事物的隔离级别,事物的传播性,事物的超时时间,事物是否只读
1)事物隔离级别:用来解决并发事物出现的问题,其使用TransactionDefinition中的静态变量来指定:
ISOLATION_DEFAULT:默认隔离级别,即使用底层数据库默认的隔离级别;
ISOLATION_READ_UNCOMMITTED:未提交读;
ISOLATION_READ_COMMITTED:提交读,一般情况下我们使用这个;
ISOLATION_REPEATABLE_READ:可重复读;
ISOLATION_SERIALIZABLE:序列化。
可以使用DefaultTransactionDefinition类中的setIsolationLevel方法来设计事物的隔离级别
2)事物传播行为:spring管理的事物是逻辑事物,物理事物与逻辑事物两者之间的区别就在于事物的传播行为,事物的传播行为指用于多个事物之间调用,事物是如何在这些方法间传播的,spring一共支持7中传播行为:
userDao.save(user);
user.getAddress().setUserId(user.getId());
addressService.save(user.getAddress());
Required:必须有逻辑事物,否则创建一个新事物PROPAGATION_REQUIRED指定,表示当前如果有事物,则加入该事物,否则创建一个新事物
一.当userService调用save()方法时,此时spring用的required传播行为并且spring事物管理器中没有开启逻辑事物,所以spring管理器会开启一个逻辑事物;
二.当addressService调用save()方法时发现同样用的required传播行为,因此使用已经存在的逻辑事物
三、在返回到addressService对象的save方法,当事务模板类执行完毕,此时提交并关闭事务。
因此userService对象的save方法和addressService的save方法属于同一个物理事务,如果发生回滚,则两者都回滚
RequiresNew:创建新的逻辑事务,使用PROPAGATION_REQUIRES_NEW指定,表示每次都创建新的逻辑事务(物理事务也是不同的),如下图:
该传播行为执行流程(正确提交情况):
一、当执行userService对象的save方法时,由于传播行为是RequiresNew,因此创建一个新的逻辑事务(物理事务也是不同的);
二、当执行到addressService对象的save方法时,由于传播行为是RequiresNew,因此首先暂停上一个逻辑事务并创建一个新的逻辑事务(物理事务也是不同的);
三、addressService对象的save方法执行完毕后,提交逻辑事务(并提交物理事务)并重新恢复上一个逻辑事务,继续执行userService对象的save方法内的操作;
四、最后userService对象的save方法执行完毕,提交逻辑事务(并提交物理事务);
五、userService对象的save方法和addressService对象的save方法不属于同一个逻辑事务且也不属于同一个物理事务。
Supports:支持当前事物,使用PROPAGATION_SUPPORTS指定,如果当前存在逻辑事物,则加入当前逻辑事物,如果没有,则以非事物方式提交
NotSupported:不支持事物,如果当前存在事物则暂停该事物,使用PROPAGATION_NOT_SUPPORTED指定,以非事物方式执行,如果当前存在逻辑事务,就把当前事务暂停,以非事务方式执行。
Mandatory:必须有事物,否则抛出异常,使用PROPAGATION_MANDATORY指定,使用当前事物执行,如果当前没有事物,则抛出异常。
Never:不支持事物,如果当前有事物则抛出异常,使用PROPAGATION_NEVER指定,即以非事物方式执行,如果当前存在事物,则抛出异常。
Nested:嵌套事物支持,使用PROPAGATION_NESTED指定,如果当前存在事物,则嵌套在事物内执行,如果当前没有事物,则创建一个新事物执行,嵌套事物是以数据库保存点来实现,即嵌套事物回滚不会影响外部事物,但外部事物回滚会影响嵌套事物。
Nested和RequiresNew的区别:
1.RequiredNew每次都是创建一个新的独立的物理事物,而Nested只有一个物理事物
2.Nested嵌套事物发生回滚不会影响外部事物,外部事物发生回滚会影响嵌套事物,而RequiredNew每次创建的都是新事物,所以并没有关联。
3.Nested使用JDBC 3的保存点实现,即如果使用低版本驱动将导致不支持嵌套事务。
使用嵌套事务,必须确保具体事务管理器实现的nestedTransactionAllowed属性为true,否则不支持嵌套事务,如DataSourceTransactionManager默认支持,而HibernateTransactionManager默认不支持,需要我们来开启。
网友评论