1:
异常类型: checked 异常(例外) 和 unchecked异常(例外)
checked 异常: 除运行期异常外的其他异常方法 声明为throw Exception 的异常,则Spring默认不会回滚
unchecked 异常: 即运行期异常 RuntimeException Spring 默认会回滚
2:
改变Spring的默认事务行为:
(1):使Spring回滚checked例外(默认不会滚):
在方法的声明上标注
@Transactional(rollbackFor=异常的名称.class)
其中异常的名称为方法抛出的异常(例外)的类名称
则Spring在遇到此checked异常时,就会回滚事务
(2):使Spring不回滚unchecked 例外(默认回滚)
在方法的声明上标注
@Transactional(noRollbackFor=RuntimeException.class)
则在方法遇到unchecked例外(运行期异常)时,则会提交事务
或者使用 noRollbackForClassName="异常的名称" 和 rollbackForClassName="异常的名称" 来指定
3:
以下的事务可以在 @Transactional(propagation=Propagation.xxx) 中的xxx即为以下事务的类型.
Spring事务的分类:
REQUIRED,NOT_SUPPORTED,REQUIRESNEW,MANDATORY,SUPPORTS,NERVER,NESTED
REQUIRED:
业务方法需要在一个事务中运行.如果方法运行时,已经处在一个事务中,那么假如到该事务,否则为自己创建一个新的事务.
NOT_SUPPORTED:
声明方法不需要事务.如果方法没有关联到一个事务,容器不会为它开启事务.如果方法在一个事务中被调用,该事务会被挂起,在方法调用结束后,原先的事务便会恢复执行.
REQUIRESNEW:
属性表明不管是否存在事务,业务方法总会为自己发起一个新的事务,容器不会为它开启事务.
如果方法已经存在一个事务中,则原有事务被挂起,新的事务会被创建,直到方法执行结束,新的事务才算结束.原先事务才会恢复执行.
MANDATORY:
该属性指定业务方法只能在一个已近存在的事务中执行,业务方法不能发起自己的事务.如果业务方法没有在事务的环境下调用,容器就会抛出例外.
SUPPORTS:
这一事务表明属性,如果业务方法在某个事务范围内被调用,则方法称为该事务的一部分.如果业务方法在事务范围外被调用,则方法在没有事务的环境下执行.
NEVER:
指定业务方法绝对不能再事务范围内执行.如果业务方法在某个事务中执行,容器会抛出异常,只有业务方法没有关联到任何事务,才能正常执行.
NESTED:
如果一个活动的事务存在,则运行一个嵌套的事务中.如果没有活动事务,则按REQUIRED属性执行.它使用了一个单独的事务,这个事务拥有多个可以回滚的保存点。内部事务的回滚不会对外部事务造成影响。但外部事务的回滚会造成内部事务的回滚. 它只对DataSourceTransactionManager事务管理器起效.
4:
@Transactional(timeout=30)
中指定事务的超时时间,一般情况下不用设置
5:
@Transactional(readOnly="")
在只读事务中使用,可以提高效率,但不可以执行增删改.
6:
@Transactional(isolation=Isolation.DEFAULT);
指定数据库的事务隔离级别:主要由底层数据库实现.
包括种类:
Read Uncommited : 读未提交数据(会出现脏数据,不可重复读和幻读)
Read Commited : 读已提交数据(会出现不可重复读和幻读) (SQLServer 默认级别)
Repeatable Read : 可重复读(会出现幻读) (MySQL 默认级别)(一般情况下是这种级别)
Serializable : 串行化
这几种级别是由数据库的不同的锁来实现:如 共享锁,更新锁,排他锁
脏读: 一个事务读取到另一个事务未提交的更新数据.
不可重复读: 在同一个事务中,多次读取同一数据返回的结果有所不同.即:后续读取可以读取另一事物已提交的更新数据.
相反,"可重复读"在同一事务多次读取数据时,能够保证所读取数据一样,也就是说,后续数据不能读到另一事物已提交的更新数据.
可重复读在数据库采取的技术为"快造"技术
幻读:一个事物读取都另一事物已提交的insert数据.
7:
使用XML方式配置Spring事务:
<aop:config>
<aop:pointcut id="transactionPointcut" expression="execution(* cn.itcast.service..*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="transactionPointcut"/>
</aop:config>
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="get*" read-only="true" propagation="NOT_SUPPORTED"/> <!-- 对读取方法采用只读 事务 -->
<tx:method name="*"/> <!-- 其他按照默认设置 如事务隔离级别 事务类型 -->
</tx:attributes>
</tx:advice>