DataSource->Connection
数据源是线程安全的,而连接不是线程安全的。每个请求都是从数据源中重新取出一个连接。
数据源一般有容器进行管理,包括连接池。
conn.setAutoCommit(false);
do something
conn.commit();//commit transcation
catch{ conn.rollback();do something}
2AOP事务控制
<!-- 扫描:指定可以使用注解的package -->
<!-- 数据源配置 -->
<bean id="dataSourceC3p0" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="oracle.jdbc.driver.OracleDriver"></property>
<property name="jdbcUrl" value="jdbc:oracle:thin:@localhost:1521:xe"></property>
<property name="user" value="kangpan"></property>
<property name="password" value="123"></property>
</bean>
<bean class="org.springframework.jdbc.core.JdbcTemplate" name="jdbcTemplate">
<!-- 构造注入关联数据源 -->
<constructor-arg>
<ref bean="dataSourceC3p0"/>
</constructor-arg>
</bean>
配置步骤:
1.Namespaces中勾选 aop tx
<!-- AOP 事务配置 -->
<!-- 1.配置事务管理器 -->
<bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" name="transactionManager">
<!-- 构造注入的方式 关联数据源 -->
<constructor-arg>
<ref bean="dataSourceC3p0"/>
</constructor-arg>
</bean>
<!-- 2.配置事务传播属性 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="save*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED"/>
<tx:method name="query*" propagation="REQUIRED"/>
<tx:method name="add*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<!-- 3.AOP配置 -->
<aop:config>
<!--定义切入点 -->
<aop:pointcut expression="execution(* pers.kp.service.impl.*.*(..))" id="txPoincut"/>
<!-- 配置连接点 -->
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPoincut"/>
</aop:config>
完整版:
<!-- 扫描 -->
<context:component-scan base-package="pers.kp.service.impl"></context:component-scan>
<!-- 引入数据库的配置文件 -->
<context:property-placeholder location="classpath:db/db.properties"/>
<!-- 数据源 -->
<!-- 数据源配置 -->
<bean id="dataSourceC3p0" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="${driverClass}"></property>
<property name="jdbcUrl" value="${jdbcUrl}"></property>
<property name="user" value="${user}"></property>
<property name="password" value="${password}"></property>
</bean>
<!-- 配置和mybatis的整合 -->
<bean class="org.mybatis.spring.SqlSessionFactoryBean" id="sqlSessionFactoryBean">
<!-- 关联的数据源 -->
<property name="dataSource" ref="dataSourceC3p0"></property>
<!-- 关联的mybatis的配置文件 -->
<property name="configLocation" value="classpath:mybatis/mybatis-config.xml"></property>
<!-- 类型别名:默认查找的包 -->
<property name="typeAliasesPackage" value="pers.kp.model"></property>
</bean>
<!-- 扫描:使用代理类的方式实现需要添加的扫描的包 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="pers.kp.mapper"></property>
</bean>
<!-- 事务的配置 -->
<bean id="txManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSourceC3p0" />
</bean>
<!-- 拦截器方式配置事物 -->
<tx:advice id="transactionAdvice" transaction-manager="txManager">
<tx:attributes>
<!-- 以如下关键字开头的方法使用事物 -->
<tx:method name="add*" propagation="REQUIRED" />
<tx:method name="save*" propagation="REQUIRED" />
<tx:method name="update*" propagation="REQUIRED"/>
<tx:method name="modify*" propagation="REQUIRED"/>
<tx:method name="edit*" propagation="REQUIRED"/>
<tx:method name="delete*" propagation="REQUIRED"/>
<tx:method name="remove*" propagation="REQUIRED"/>
<tx:method name="buyfood" propagation="REQUIRED"/>
<tx:method name="order" propagation="REQUIRED"/>
<!-- 以如下关键字开头的方法不使用事物 -->
<tx:method name="get*" read-only="true"/>
<tx:method name="find*" read-only="true" />
<tx:method name="load*" read-only="true" />
<tx:method name="query*" read-only="true" />
<!-- 其他方法不使用事物 -->
<tx:method name="*" propagation="SUPPORTS" />
</tx:attributes>
</tx:advice>
<!-- 切面,将事物用在哪些对象上 -->
<aop:config>
<aop:pointcut id="transactionPointcut" expression="execution(* pers.kp.service.impl.*Impl.*(..))" />
<aop:advisor pointcut-ref="transactionPointcut" advice-ref="transactionAdvice" />
</aop:config>