1.事务怎么控制的?
sqlsession.commit() sqlsession.roolback()
connection.commit() connection.roolback()
2.控制事务的关键对象是谁?
connection
3.怎么从业务层获取到连接对象?
将连接池对象注入到service实现类中,从而获取到连接对象
4.代码冗余
由于将连接池注入到service之后,手动控制增删改的事务 出现了大量的
代码冗余 解决该问题可以使用面向切面编程
5.编码示例
MyTransactionAdvice implments MethodInterceptor{
private DruidDatasource datasource;
public void setDataSource(DruidDataSource dataSource) {
this.dataSource = dataSource;
}
public Object invoke(MethodInvocation methodInvocation){
Connection conn=datasource.getConnection();
try{
conn.setAutoCommit(false);
//目标方法
methodInvocation.proceed();
conn.commit()
}catch(Exception e){
conn.roolback()
}
}
}
6. //将通知对象交由工厂管理
<bean id="advice" class="MyTransactionAdvice">
<property name="dataSource" ref="datasource"/>
</bean>
<aop:config>
<aop:pointcut id=“pt” expression="excuction(* com.baihzi.service.*.*(..))"/>
<aop:advisor pointcut-ref="pt" advice-ref="advice">
</aop:config>
7.对于手动控制事务 会造成线程安全的问题?
在spring中提供一个类 DataSourceTransactionManager(当前类
可以保证service 和dao拿到的是同一个连接)
//创建线程安全的DataSourceTransactionManager
<bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="datasource" ref="dataSource">
</bean>
//控制事务的通知类 依赖DataSourceTransactionManager
<tx:advice id="advice" TransactionManager="dataSourceTransactionManager">
</tx:advice>
<aop:config>
<aop:pointcut id=“pt” expression="excuction(* com.baihzi.service.*.*(..))"/>
<aop:advisor pointcut-ref="pt" advice-ref="advice">
</aop:config>