Spring中的事务控制。
PlatformTransactionManager
Spring的事务管理器,提供了常用的操作事务的方法,我们在开发中都使用它的实现类。
| 1 | //获取事务状态信息 | 
真正管理事务的对象
| 1 | org。springframework。jdbc。datasource。DataSourceTransactionManager//使用Spring JDBC或iBatis进行持久化数据时使用 | 
TransactionDefinition
事务的定义信息对象,有如下方法:
- 
String getName(): 获取事务对象名称
- 
int getIsolationLevel(): 获取事务隔离级别,设置两个事务之间的数据可见性- ISOLATION_DEFAULT: Spring事务管理的的默认级别,使用数据库默认的事务隔离级别
- ISOLATION_READ_UNCOMMITTED: 读未提交
- ISOLATION_READ_COMMITTED: 读已提交,解决脏读问题
- ISOLATION_REPEATABLE_READ: 是否读取其他事务提交修改后的数据,解决不可重复读问题
- ISOLATION_SERIALIZABLE: 串行化,是否读取其他事务提交添加后的数据,解决幻影读问题
 
- 
int getPropagationBehavior(): 获取事务传播行为,设置新事务是否事务以及是否使用当前事务通常使用的是前两种 REQUIRED和SUPPORTS,事务传播行为如下:- REQUIRED: Spring默认事务传播行为。 若当前没有事务,就新建一个事务;若当前已经存在一个事务中,加入到这个事务中。增删改查操作均可用
- SUPPORTS: 若当前没有事务,就不使用事务;若当前已经存在一个事务中,加入到这个事务中。查询操作可用
- MANDATORY: 使用当前的事务,若当前没有事务,就抛出异常
- REQUERS_NEW: 新建事务,若当前在事务中,把当前事务挂起
- NOT_SUPPORTED: 以非事务方式执行操作,若当前存在事务,就把当前事务挂起
- NEVER:以非事务方式运行,若当前存在事务,抛出异常
- NESTED:若当前存在事务,则在嵌套事务内执行;若当前没有事务,则执行REQUIRED类似的操作
 
- 
int getTimeout(): 获取事务超时时间默认值是-1,没有超时限制。如果有以秒为单位进行设置 
- 
boolean isReadOnly(): 获取事务是否只读建议查询时设置为只读 
TransactionStatus
事务状态信息对象,提供操作事务状态的方法如下:
- void flush(): 刷新事务
- boolean hasSavepoint(): 查询是否存在存储点,事务的一步,按步提交
- boolean isCompleted(): 查询事务是否完成
- boolean isNewTransaction(): 查询是否是新事务
- boolean isRollbackOnly(): 查询事务是否回滚
- void setRollbackOnly(): 设置事务回滚
基于XML的声明式事务配置
- 
配置事务管理器 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25<!--新的约束--> 
 <beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:aop="http://www.springframework.org/schema/aop"
 xmlns:tx="http://www.springframework.org/schema/tx"
 xsi:schemaLocation="
 http://www.springframework.org/schema/beans
 https://www.springframework.org/schema/beans/spring-beans.xsd
 http://www.springframework.org/schema/tx
 https://www.springframework.org/schema/tx/spring-tx.xsd
 http://www.springframework.org/schema/aop
 https://www.springframework.org/schema/aop/spring-aop.xsd">
 <!--配置数据源-->
 <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
 <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
 <property name="url" value="jdbc:mysql://localhost:3306/test"></property>
 <property name="username" value="root"></property>
 <property name="password" value="root"></property>
 </bean>
 <!--配置事务管理器-->
 <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
 <property name="dataSource" ref="dataSource"></property>
 </bean>
 </beans>
- 
配置事务的通知,此时需要导入事务的约束 1 <tx:advice id="txAdvice" transaction-manager="transactionManager"></tx:advice> 
- 
配置AOP中切入点表达式 
- 
建立事务通知和切入点表达式的对应关系 1 
 2
 3
 4
 5
 6<!--配置切入点表达式--> 
 <aop:config>
 <aop:pointcut id="pt1" expression="execution(* com.ztygalaxy.service.impl.*.*(..))"/>
 <!--配置切入点表达式和事务通知的对应关系-->
 <aop:advisor advice-ref="txAdvice" pointcut-ref="pt1"></aop:advisor>
 </aop:config>
- 
配置事务的属性,在事务的通知tx:advice标签内部配置。 - isolation: 用于指定事务的隔离级别,默认值是DEFAULT,表示使用数据库的默认隔离级别。
- no-rollback-for: 用于指定一个异常,当产生该异常时,事务不回滚。没有默认值,表示任何异常都回滚。
- propagation: 用于指定事务的传播行为,默认值是REQUIRED,表示一定会有事务,增删改的选择。查询方法可以选择SUPPORTS。
- read-only: 用于指定事务是否只读,只有查询方法才能设置为true,默认值是false,表示读写。
- rollback-for: 用于指定一个异常,当产生一个异常时,事务回滚,产生其他异常时不回滚。没有默认值,表示任何异常值都回滚。
- timeout: 用于指定事务的超时时间,默认值是-1,表示永不超时,如果制定了数值,以秒为单位。
 1 
 2
 3
 4
 5
 6
 7
 8
 9<!--配置事务的通知--> 
 <tx:advice id="txAdvice" transaction-manager="transactionManager">
 <tx:attributes>
 <!--通配符-->
 <tx:method name="*" propagation="REQUIRED" read-only="false"/>
 <!--查询方法-->
 <tx:method name="find*" propagation="SUPPORTS" read-only="true"/>
 </tx:attributes>
 </tx:advice>
基于注解的声明式事务控制
- 
配置事务管理器 
- 
开启spring对注解事务的支持 1 
 2
 3
 4
 5
 6//Dao中取消JDBCSupport 
 public class AccountDaoImpl extends JdbcDaoSupport implements IAccountDao {
 
 private JdbcTemplate jdbcTemplate;
 }1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 <beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:aop="http://www.springframework.org/schema/aop"
 xmlns:tx="http://www.springframework.org/schema/tx"
 xmlns:context="http://www.springframework.org/schema/context"
 xsi:schemaLocation="
 http://www.springframework.org/schema/beans
 https://www.springframework.org/schema/beans/spring-beans.xsd
 http://www.springframework.org/schema/tx
 https://www.springframework.org/schema/tx/spring-tx.xsd
 http://www.springframework.org/schema/aop
 https://www.springframework.org/schema/aop/spring-aop.xsd
 http://www.springframework.org/schema/context
 https://www.springframework.org/schema/context/spring-context.xsd">
 <context:component-scan base-package="com.ztygalaxy"></context:component-scan>
 <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
 <property name="dataSource" ref="dataSource"></property>
 </bean>
 <!--配置数据源-->
 <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
 <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
 <property name="url" value="jdbc:mysql://localhost:3306/test"></property>
 <property name="username" value="root"></property>
 <property name="password" value="root"></property>
 </bean>
 <!--spring中基于声明式事务配置-->
 <!--配置事务管理器-->
 <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
 <property name="dataSource" ref="dataSource"></property>
 </bean>
 <!--开启spring对注解事务的支持-->
 <tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
 </beans>
- 
在需要事务支持的地方使用 @Transaction注解1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 public class AccountServiceImpl implements IAccountService {}
 //或者对整个类定义后,对单个方法修改
 public class AccountServiceImpl implements IAccountService {
 
 public void transfer(String sourceName, String targetName, Float money) {}
 }
基于纯注解的事务配置
- 
事务控制配置类 TransactionConfig1 
 2
 3
 4
 5
 6
 7public class TransactionConfig { 
 //用于创建事务管理器对象
 
 public PlatformTransactionManager createTransactionManager(DataSource dataSource){
 return new DataSourceTransactionManager(dataSource);
 }
 }
- 
JDBC配置类 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29public class JdbcConfig { 
 
 private String driver;
 
 private String url;
 
 private String username;
 
 private String password;
 //创建JdbcTemplate对象
 
 public JdbcTemplate createJdbcTemplate(DataSource dataSource){
 return new JdbcTemplate(dataSource);
 }
 //创建数据源对象
 
 public DataSource createDataSource(){
 DriverManagerDataSource ds=new DriverManagerDataSource();
 ds.setDriverClassName(driver);
 ds.setUrl(url);
 ds.setUsername(username);
 ds.setPassword(password);
 return ds;
 }
 }
- 
JDBC配置文件 1 
 2
 3
 4jdbc.driver=com.mysql.jdbc.Driver 
 jdbc.url=jdbc:mysql://localhost:3306/test
 jdbc.username=root
 jdbc.password=root
- 
总配置类 1 
 2
 3
 4
 5
 6
 7
 public class SpringConfiguration {
 }
- 
测试类 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 public class AccountService {
 
 private IAccountService as;
 
 public void transfer(){
 as.transfer("bbb","ccc",234f);
 }
 }
Spring编程式事务控制
Spring的编程式事务控制不能实现解耦,反而使耦合更加严重了,因此不推荐使用。
