一、事务
1.1事物的特性
原子性、持久性、一致性、隔离性
1.2不考虑隔离性存在的安全问题
读问题:脏读、不可重复读、幻读、
写问题:写更新丢失
1.3读问题的解决方案
设置隔离级别:由低到高:读未提交,读已提交,可重复读,可串行化(自己翻译的,Serializable)。
1.4写问题的解决方案
方案一:数据库设置
方案二:程序员手动实现,通常通过比对更新版本号
二、spring事务管理的介绍
事务平台管理器 PlatformTransactionManager:接口
事务定义信息 TransactionDefinition
事务的状态 TransactionStatus
事务的传播行为 :
Spring中提供了七种事务的传播行为:
类别一:保证多个操作在同一个事务中
- PROPAGATION_REQUIRED :默认值,如果A中有事务,使用A中的事务,如果A没有,创建一个新的事务,将操作包含进来
- PROPAGATION_SUPPORTS :支持事务,如果A中有事务,使用A中的事务。如果A没有事务,不使用事务。
- PROPAGATION_MANDATORY :如果A中有事务,使用A中的事务。如果A没有事务,抛出异常。
类别二:保证多个操作不在同一个事务中
- PROPAGATION_REQUIRES_NEW :如果A中有事务,将A的事务挂起(暂停),创建新事务,只包含自身操作。如果A中没有事务,创建一个新事务,包含自身操作。
- PROPAGATION_NOT_SUPPORTED :如果A中有事务,将A的事务挂起。不使用事务管理。
- PROPAGATION_NEVER :如果A中有事务,报异常。
类别三:嵌套式事务
- PROPAGATION_NESTED :嵌套事务,如果A中有事务,按照A的事务执行,执行完成后,设置一个保存点,执行B中的操作,如果没有异常,执行通过,如果有异常,可以选择回滚到最初始位置,也可以回滚到保存点。
三、spring事务管理的三种操作实现
1.编程式事务
大致步骤:
步骤一:搭建spring,基础IOC,AOP环境,还有JDBC的环境,最后还有事务管理的jar包(tx)。
步骤二:配置平台事务管理器(org.springframework.jdbc.datasource.DatasourceTransactionManager)、
事务模板类(org.springframework.transaction.support.TransactionTemplate)
步骤三:利用事务模板类.execute(new TransactionCallbackWithoutResult(){ 事务所在的方法 })
2.声明式事务
2.1XML的方式
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 配置连接池,获得DataSource -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql:///spring4_day03"/>
<property name="user" value="root"/>
<property name="password" value="a"/>
</bean>
<!-- 配置DAO -->
<bean id="accountDao" class="testSpring.tx.temp.AccountDaoimpl">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 配置service -->
<bean id="accountService" class="testSpring.tx.temp.AccountServiceImple">
<property name="accountDao" ref="accountDao"></property>
</bean>
<!-- 配置事务管理器=============================== -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 配置事务的增强==可以配置tx:aspect多个切面,多个切入点============================= -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!-- 事务管理的规则 -->
<!-- <tx:method name="save*" propagation="REQUIRED" isolation="DEFAULT"/>
<tx:method name="update*" propagation="REQUIRED"/>
<tx:method name="delete*" propagation="REQUIRED"/>
<tx:method name="find*" read-only="true"/> -->
<tx:method name="*" propagation="REQUIRED" read-only="false"/>
</tx:attributes>
</tx:advice>
<!-- aop的配置 -->
<aop:config>
<aop:pointcut expression="execution(* testSpringJDBC.temp.test.*(..))" id="pointcut1"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut1"/>
</aop:config>
</beans>
2.2注解的方式
<!-- 去除切面的配置,只留下事务管理平台的配置,在类的声明前加入@Transactional.即可 -->
<tx:annotation-driven transaction-manager="transactionManager"/>