JdbcTemplate


JdbcTemplate基础用法:Insert语句

JdbcTemplate基础用法:Update语句

JdbcTemplate基础用法:Select语句

JdbcTemplate基础用法:NamedParameterJdbcTemplate


事务
事务的4个关键属性(ACID):
A:原子性atomicity,事务是一个原子操作,由一系列动作组成,事务的原子性确保动作要么全部完成,要么完全不起作用。
C:一致性consistency,一旦所有事务动作完成,事务就被提交,数据和资源就处于一种满足业务规则的一致性状态。
I:隔离性isolation,可能有许多事务会同时处理相同的数据,因此每个事务都应该与其他事务隔离开来,防止数据损坏。
D:持久性durability,一旦事务完成,无论发生什么系统错误,其结果都不应该受到影响,通常情况下,事务的结果被写到持久化存储器中。
Spring在不同的事务管理API之上又定义了一个抽象层,而应用程序开发人员不必了解底层的事务管理API,这就是Spring事务管理大致设计。
Spring既可以支持编程式事务管理,又支持声明式的事务管理;
所谓编程式事务管理是将事务管理代码嵌入到业务方法中来控制事务的提交和回滚,因此必须在每个事务操作中包含额外的事务管理代码;
而声明式事务管理大多数情况下比编程式事务管理更好用,它是将事务管理代码从业务方法中分离出来,然后以声明的方式来实现事务管理,声明式事务管理可以作为一种横切关注点,可以通过AOP方法模块化,Spring就是通过AOP框架来支持声明式事务管理的。
Spring核心事务管理抽象是PlutfromTransactionManager,里面封装了一组独立于技术的方法,无论采用哪种事务管理策略,事务管理器都是必须的。

事务:用注解来配置声明式事务


注意:tx命名空间
事务:事务传播属性
当事务方法被另一个事务方法调用时,必须指定事务应该如何传播,例如:方法可能继续在现有事务中运行,也可能开始一个新事务,并在自己的事务中运行。
通俗来讲就是具有事务的方法A,去调用也具有事务的方法B,怎么处理A与B中的事务,这就是事务的传播属性。
事务的传播行为可以由属性propagation来定义,Spring定义了7种传播行为:
①Propagation.required:默认值,表示当前方法必须运行在事务中。如果当前事务存在,方法将会在该事务中运行,否则,会启动一个新的事务。
②Propagation.supports:表示当前方法不需要事务上下文,但是如果存在当前事务的话,那么该方法会在这个事务中运行。
③Propagation.mandaory:表示该方法必须在事务中运行,如果当前事务不存在,则会抛出一个异常。
④Propagation.required_new:表示当前方法必须在它自己的事务中,一个新事务将被启动。如果存在当前事务,则在该方法执行期间,当前事务会被挂起;如果使用JITATransactionManager的话,则需要访问TransactionManager。
⑤Propagation.not_supported:表示该方法不应该运行在事务中。如果存在当前事务,则在该方法运行期间,当前事务被挂起;如果使用JITATransactionManager的话,则需要访问TransactionManager。
⑥Propagation.never:表示当前方法不应该运行在事务上下文中。如果当前正有一个事务在运行,则会抛出异常。
⑦Propagation.nested:表示如果当前已经存在一个事务,那么该方法将会在嵌套事务中运行。嵌套的事务可以独立于当前事务进行单独地提交/回滚;如果当前事务不存在,那么其行为与propagation_required一样。

事务:事务隔离级别
当同一个应用程序或者不同应用程序中的多个事务在同一个数据集上并发执行时,可能会出现许多意外问题,并发事务导致的问题大致分为下面3种类型:
①脏读:对于两个事务T1和T2,T1读取了已经被T2更新但还没有被提交的字段,后续若T2回滚则T1读取的内容就是临时且无效的数据。
②不可重复读:对于两个事务T1和T2,T1读取一个字段,然后T2更新了该字段,后续当T1再次读取同一个字段时,值就不同了。
③幻读:对于两个事务T1和T2,T1从一个表中读取了一个字段,然后T2在该表中插入新的行,后续如果T1再次读取同一个表,则会多出几行数据。

这里Spring通过isolation来解决该问题。isolation属性取值范围如下:
①Isolation.READ UNCOMMITTED(读未提交数据):允许事务读取未被其他事务提交的变更数据,会出现脏读、不可重复读和幻读问题。
②Isolation.READ COMMITTED(读已提交数据):只允许事务读取已经被其他事务提交的变更数据,可避免脏读,仍会出现不可重复读和幻读问题。
③Isolation.REPEATABLE READ(可重复读):确保事务可以多次从一个字段中读取相同的值,在此事务持续期间,禁止其他事务对此字段的更新,可以避免脏读和不可重复读,仍会出现幻读问题。
④Isolation.SERIALIZABLE(序列化):确保事务可以从一个表中读取相同的行,在这个事务持续期间,禁止其他事务对该表执行插入、更新和删除操作,可避免所有并发问题,但性能非常低。


事务:回滚
Spring的声明式事务默认对所有的运行时异常都进行回滚,但也可以通过对应的rollbackFor、rollbackForClassName、noRollbackFor、noRollbackForClassName属性进行设置。
这里以noRollbackFor 为例来进行说明:
noRollbackFor = {XXXException.class},即针对XXXException异常不进行回滚。

事务:只读
表示这个事务只读取数据,不更新数据,这样可以帮助数据库引擎优化事务。如果是select语句则设置readOnly=true。

事务:超时
限制当前事务在timeout秒内完成,否则强制事务回滚。

事务:基于XML配置事务
|
<!-- 1.声明bean --> <bean id="transaction2" class="com.suntj.spring.transaction.Transaction2"> <property name="jdbcTemplate" ref="jdbcTemplate"/> </bean> <!-- 2.配置事务管理器 --> <bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="comboPooledDataSource"/> </bean> <!-- 3.配置事务各种属性 --> <tx:advice id="txAdvice" transaction-manager="dataSourceTransactionManager"> <tx:attributes> <!-- 根据方法名,来指定具体方法的具体事务属性 --> <tx:method name="updateAccount" propagation="REQUIRED" isolation="READ_COMMITTED" read-only="false" timeout="3"/> <tx:method name="get*" read-only="true"/> </tx:attributes> </tx:advice> <!-- 4.配置事务切点,并关联事务的各种属性 --> <aop:config> <!-- 配置切点表达式 --> <aop:pointcut id="txPointcut" expression="execution(public void com.suntj.spring.transaction.Transaction2.updateAccount())"/> <!-- 配置切面及通知 --> <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/> </aop:config> |
7833

被折叠的 条评论
为什么被折叠?



