什么是事务?
事务指数据库中多个操作合并在一起形成的操作序列
事务的隔离级
-
脏读:允许读取未提交的信息
-
原因:Read uncommitted
解决方案: (表级读锁)
-
-
不可重复读:读取过程中单个数据发生了变化
-
解决方案: Repeatable read (行级写锁)
-
-
幻读:读取过程中数据条目发生了变化
-
解决方案: Serializable(表级写锁)
-
平台事务管理器实现类
-
DataSourceTransactionManager 适用于Spring JDBC或MyBatis
-
HibernateTransactionManager 适用于Hibernate3.0及以上版本
-
JpaTransactionManager 适用于JPA
-
JdoTransactionManager 适用于JDO
-
JtaTransactionManager 适用于JTA
-
获取事务
-
TransactionStatus getTransaction(TransactionDefinition definition)
提交事务 :
-
void commit(TransactionStatus status)
回滚事务 :
-
void rollback(TransactionStatus status)
TransactionDefinition
此接口定义了事务的基本信息
-
获取事务定义名称
-
String getName()
获取事务的读写属性
-
boolean isReadOnly()
获取事务隔离级别
-
int getIsolationLevel()
获事务超时时间
-
int getTimeout()
获取事务传播行为特征
-
int getPropagationBehavior()
编程式事务
-
public void transfer(String outName,String inName,Double money){ //创建事务管理器 DataSourceTransactionManager dstm = new DataSourceTransactionManager(); //为事务管理器设置与数据层相同的数据源 dstm.setDataSource(dataSource); //创建事务定义对象 TransactionDefinition td = new DefaultTransactionDefinition(); //创建事务状态对象,用于控制事务执行 TransactionStatus ts = dstm.getTransaction(td); accountDao.inMoney(outName,money); int i = 1/0; //模拟业务层事务过程中出现错误 accountDao.outMoney(inName,money); //提交事务 dstm.commit(ts); }
使用AOP控制事务
将业务层的事务处理功能抽取出来制作成AOP通知,利用环绕通知运行期动态织入
-
public Object tx(ProceedingJoinPoint pjp) throws Throwable { DataSourceTransactionManager dstm = new DataSourceTransactionManager(); dstm.setDataSource(dataSource); TransactionDefinition td = new DefaultTransactionDefinition(); TransactionStatus ts = dstm.getTransaction(td); Object ret = pjp.proceed(pjp.getArgs()); dstm.commit(ts); return ret; }
配置AOP通知类,并注入dataSource
-
<bean id="txAdvice" class="com.itheima.aop.TxAdvice"> <property name="dataSource" ref="dataSource"/> </bean>
使用环绕通知将通知类织入到原始业务对象执行过程中
-
<aop:config> <aop:pointcut id="pt" expression="execution(* *..transfer(..))"/> <aop:aspect ref="txAdvice"> <aop:around method="tx" pointcut-ref="pt"/> </aop:aspect> </aop:config>
声明式事务(XML)
AOP配置事务是否具有特例性?
-
public Object tx(ProceedingJoinPoint pjp) throws Throwable { DataSourceTransactionManager dstm = new DataSourceTransactionManager(); dstm.setDataSource(dataSource); TransactionDefinition td = new DefaultTransactionDefinition(); TransactionStatus ts = dstm.getTransaction(td); Object ret = pjp.proceed(pjp.getArgs()); dstm.commit(ts); return ret; }
<bean id="txAdvice" class="com.itheima.aop.TxAdvice"> <property name="dataSource" ref="dataSource"/> </bean>
使用tx命名空间配置事务专属通知类
-
<tx:advice id="txAdvice" transaction-manager="txManager"> <tx:attributes> <tx:method name="*" read-only="false" /> <tx:method name="get*" read-only="true" /> <tx:method name="find*" read-only="true" /> </tx:attributes> </tx:advice>
使用aop:advisor在AOP配置中引用事务专属通知类
-
<aop:config> <aop:pointcut id="pt" expression="execution(* *..*(..))"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="pt"/> </aop:config>
声明式事务(纯注解驱动)
-
名称:@EnableTransactionManagement
-
类型:类注解
-
位置:Spring注解配置类上方
-
作用:开启注解驱动,等同XML格式中的注解驱动
-
范例:
-
@Configuration @ComponentScan("com.itheima") @PropertySource("classpath:jdbc.properties") @Import({JDBCConfig.class,MyBatisConfig.class,TransactionManagerConfig.class}) @EnableTransactionManagement public class SpringConfig { }
public class TransactionManagerConfig { @Bean public PlatformTransactionManager getTransactionManager(@Autowired DataSource dataSource){ return new DataSourceTransactionManager(dataSource); } }