最终的事务提交
主要有2个实现
1.hibernate
2.数据源
即调用的是orm框架的事务,orm框架的事务调用的又是jdbc客户端即jdbc api 连接connection的提交方法。
hibernate
public class HibernateTransactionManager extends AbstractPlatformTransactionManager implements ResourceTransactionManager, BeanFactoryAware, InitializingBean {
protected void doCommit(DefaultTransactionStatus status) {
//获取hibernate事务管理器
HibernateTransactionManager.HibernateTransactionObject txObject = (HibernateTransactionManager.HibernateTransactionObject)status.getTransaction();
if (status.isDebug()) {
this.logger.debug("Committing Hibernate transaction on Session [" + SessionFactoryUtils.toString(txObject.getSessionHolder().getSession()) + "]");
}
try {
//提交事务
txObject.getSessionHolder().getTransaction().commit(); //提交事务
} catch (TransactionException var4) {
throw new TransactionSystemException("Could not commit Hibernate transaction", var4);
} catch (HibernateException var5) {
throw this.convertHibernateAccessException(var5);
}
}
数据源
public class DataSourceTransactionManager extends AbstractPlatformTransactionManager implements ResourceTransactionManager, InitializingBean {
protected void doCommit(DefaultTransactionStatus status) {
//获取数据源事务管理器
DataSourceTransactionManager.DataSourceTransactionObject txObject = (DataSourceTransactionManager.DataSourceTransactionObject)status.getTransaction();
Connection con = txObject.getConnectionHolder().getConnection();
if (status.isDebug()) {
this.logger.debug("Committing JDBC transaction on Connection [" + con + "]");
}
try {
//提交事务
con.commit(); //提交事务
} catch (SQLException var5) {
throw new TransactionSystemException("Could not commit JDBC transaction", var5);
}
}
线程
一个请求下来,这个请求线程可能包含了很多个事务,那怎么传播事务?
1.每个事务,都创建新的事务
2.只创建第一个事务,后面的事务共用第一个事务,就不创建新的事务了
各自的优缺点?应用场景?
略。
公司系统目前是哪种情况?传播规则是怎样的?
配置
<!-- transaction -->
<bean id="transactionManager_trade"
class="org.springframework.orm.hibernate3.HibernateTransactionManager"> //hibernate事务管理器
<property name="sessionFactory">
<ref bean="sessionFactory_trade" />
</property>
</bean>
<!-- 声明式事务-->
<tx:advice id="txAdvice_trade" transaction-manager="transactionManager_trade">
<tx:attributes>
<tx:method name="get*" propagation="SUPPORTS" read-only="true" />
<tx:method name="insert*" rollback-for="hikefa.core.exception.BizException" />
<tx:method name="update*" rollback-for="hikefa.core.exception.BizException" />
<tx:method name="delete*" rollback-for="hikefa.core.exception.BizException" />
<tx:method name="*" rollback-for="hikefa.core.exception.BizException" /> //所有方法都加事务
</tx:attributes>
</tx:advice>
<aop:config proxy-target-class="true">
<aop:advisor advice-ref="txAdvice_trade" pointcut="execution(* xxx.trade.dbservice.impl..*Service*.*(..))" /> //所有service类的所有业务方法都加事务
</aop:config>
默认传播规则是?
如果当前线程已经有事务,就不创建新的事务。如果没有,才创建新的事务。
举例说明,总结
1.代码
非service类的方法(){
1.调用service1.方法; //比如,创建支付订单
2.调用service2.方法。//比如,创建支付订单明细
}
2.那么现在的事务传播规则是?
1)调用service1.方法 //方法结束之后,就已经提交事务了
2)调用service2.方法 //由于上面的事务已经提交和结束了,所以这次又会创建新的事务对象,然后在方法结束的时候,这个新的事务对象会去提交事务
3.spring默认的事务传播规则是?
代码
service0类的业务方法(){ //创建新的事务
1.调用service1类.业务方法; //当前线程已经有了事务,就不再创建新的事务对象 //方法结束的时候,那还提交吗?
2.调用service2类.业务方法。//当前线程已经有了事务,就不再创建新的事务对象 //方法结束的时候,那还提交吗?
}
这个时候,相当于有3个事务,但是是共用一个(即共用第一个事务对象),但是提交事务是每次每个方法结束的时候提交,还是最后一起提交(即由service0类的业务方法结束的时候提交),只提交一次?
只提交一次,因为事务是原子操作,不管这个事务包含了几个子事务(即嵌套事务),所以如果有嵌套事务,就以最外层的事务为准,它提交才是真的提交,而且最外层的事务只提交一次,就是在最外层的业务方法结束的时候。
表示事务对象的核心类和线程的关系
每个请求线程的事务是如何和当前线程绑定的?基于ThreadLocal。
参考
深入解析spring架构和实现原理