近期项目中用到了jdbctemplate事物,对一些知识点进行简单的总结。
1.queryForObject查不到记录的时候会报异常。queryFor 不会。
2.spring提供了对事物的支持。在配置类增加bean,,构造函数的参数是datasource.
@Bean(name="transactionManager")
public DataSourceTransactionManager getTransactionManager(){
return new DataSourceTransactionManager(this.dataSource());
}
然后在DAO类上增加注解:@Transactional,就可以指定这个类需要受Spring的事务管理 默认Spring为每个方法开启一个事务,如果方法发生运行期错误unchecked(RuntimeException),事务会进行回滚 如果发生checked Exception,事务不进行回滚. 也可以在具体的方法上加上此注解,而不需要使整个类都受影响。3.复习一下何为checked和unchecked异常。
a,Throwable类是所有异常的始祖,它有两个直接子类Error / Exception:
Error仅在Java虚拟机中发生动态连接失败或其它的定位失败的时候抛出一个Error对象。一般程序不用捕捉或抛出Error对象。
b.Unchecked Exception:
a. 指的是程序的瑕疵或逻辑错误,并且在运行时无法恢复。
b. 包括Error与RuntimeException及其子类,如:OutOfMemoryError, UndeclaredThrowableException, IllegalArgumentException, IllegalMonitorStateException, NullPointerException, IllegalStateException, IndexOutOfBoundsException等。
c. 语法上不需要声明抛出异常。
c.Checked Exception:
说了这么多,感觉还是似懂非懂。但是,SQLException是checked异常,上面说了,spring支持的是unchecked异常,那他如何实现事物的呢,查看源码,原来在jdbctemplate的执行方法中,会捕获SQLException然后抛出org.springframework.dao.DataAcceddException,org.springframework.core.NestedRuntimeException,NestedRuntimeExceptiona. 代表程序不能直接控制的无效外界情况(如用户输入,数据库问题,网络异常,文件丢失等)
b. 除了Error和RuntimeException及其子类之外,如:ClassNotFoundException, NamingException, ServletException, SQLException, IOException等。
c. 需要try catch处理或throws声明抛出异常。
是一个继承自RuntimeException的抽象类,Spring jdbcTemplate处理发生异常处理后抛出来得异常基本上都会继承NestedRuntimeException,这种异常属于unchecked异常。这就通了可以修改Spring的默认配置,当发生RuntimeException我们也可以不让他进行事务回滚 只需要加上一个@Transactional(noRollbackFor=RuntimeException.class)
注意@Transactional只能针对public属性范围内的方法添加
可以配置对Exception进行回滚,主要用到的是 @Transactional(rollbackFor=Exception.class)
对于一些查询工作,因为不需要配置事务支持,我们配置事务的传播属性: @Transactional(propagation=Propagation.NOT_SUPPORTED,readOnly=true)
readOnly=true表示事务中不允许存在更新操作.
关于事务的传播属性有下面几种配置:
REQUIRED:业务方法需要在一个事务中运行,如果方法运行时,已经处于一个事务中,那么加入到该事务中,否则自己创建一个新的事务.(Spring默认的事务传播属性)
NOT_SUPPORTED:声明方法不需要事务,如果方法没有关联到一个事务,容器不会为它开启事务,如果方法在一个事务中被调用,该事务被挂起,在方法调用结束后,原先的事务便会恢复执行
REQUIRESNEW:不管是否存在事务,业务方法总会为自己发起一个新的事务,如果方法运行时已经存在一个事务,则该事务会被挂起,新的事务被创建,知道方法执行结束,新事务才结束,原先的事务才恢复执行.
MANDATORY:指定业务方法只能在一个已经存在的事务中执行,业务方法不能自己发起事务,如果业务方法没有在事务的环境下调用,则容器会抛出异常
SUPPORTS:如果业务方法在事务中被调用,则成为事务中的一部分,如果没有在事务中调用,则在没有事务的环境下执行
NEVER:指定业务方法绝对不能在事务范围内运行,否则会抛出异常.
NESTED:如果业务方法运行时已经存在一个事务,则新建一个嵌套的事务,该事务可以有多个回滚点,如果没有事务,则按REQUIRED属性执行. 注意:业务方法内部事务的回滚不会对外部事务造成影响,但是外部事务的回滚会影响内部事务
具体例子:
待续。