Spring c3p0的测试 和 事物管理 xml配置

栏目: Java · 发布时间: 7年前

内容简介:Spring c3p0的测试 和 事物管理 xml配置

一,使用c3p0配置连接池的xml配置

c3p0.jar 和mchange-commons-java.jar

a.CombopooledDataSource 连接池底层的原理实现 :java

{
				ComboPooledDataSource datesource=
					new ComboPooledDataSource();
			//其实不需要配置文件也行,只是需要写死就ok
			datesource.setDriverClass("com.mysql.jdbc.Driver");
			datesource.setJdbcUrl("jdbc:mysql:///message");
			datesource.setUser("root");
			datesource.setPassword("");
			JdbcTemplate jdbcTemplate = new JdbcTemplate(datesource);
			String sql = "select count(*) from message";
			int i = jdbcTemplate.queryForInt(sql);
			System.out.println(i);
			}

b.spring中配置c3p0的连接池

<!-- 1.配置c3p0 的连接池 -->
			<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
				<!-- 注入属性值 -->
				<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
				<property name="jdbcUrl" value="jdbc:mysql:///message"></property>
				<property name="user" value="root"></property>
				<property name="password" value=""></property>
			</bean>
				<!-- 2.创建jdbcTemplate模板 -->
			<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
				<property name="dataSource" ref="dataSource"></property>
			</bean>
			<!-- 3.给userDao中注入jdbcTemplate模板 -->
			<bean id="userDao" class="com.gog.c3p0.UserDao">
				<property name="jdbcTemplate" ref="jdbcTemplate"></property>
			</bean>
			<!-- 4. -->
			<bean id="userService" class="com.gog.c3p0.UserService">
				<property name="userDao" ref="userDao"></property>
			</bean>

c.userDao中实现对数据库的操作

public class UserDao {
				private JdbcTemplate jdbcTemplate;
				public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
					this.jdbcTemplate = jdbcTemplate;
				}
				public void add(){
					System.out.println("--> UserDao");
					String sql = " insert into message values(?,?,?,?)";
					int rows = jdbcTemplate.update(sql, 72, "GGr", "3", "4");
					System.out.println("rows"+rows);
				}
			}

二,Spring 的事物 的xml配置

tip:

事物是操作数据的一组操作的基本单元,要不然都成功,要不都失败

不考虑隔离性产生读问题 -->多个事物之间不产生影响

(1)编程试事物管理

不常用

(2)声明式事物管理

PlatformTransactionManager 事物管理接口

TransactionDefinition事物定义信息(隔离,传播,超时,只读)

TransactionStatus事物具体运行状态

1)基于xml配置文件实现

2)注解实现

<!-- 开启注解扫描 -->
	<context:component-scan base-package="com.gog"></context:component-scan>
	<!-- 开启aop注解操作(自动代理) -->
	<aop:aspectj-autoproxy></aop:aspectj-autoproxy>


	<!-- 1.配置c3p0 的连接池 -->
	<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<!-- 注入属性值 -->
		<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
		<property name="jdbcUrl" value="jdbc:mysql:///message?useUnicode=true&characterEncoding=utf8"></property>
		<property name="user" value="root"></property>
		<property name="password" value=""></property>
	</bean>
	<!-- 2.创建jdbcTemplate模板 -->
	<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
		<property name="dataSource" ref="dataSource"></property>
	</bean>
	
	<!-- 1.xml配置事物管理器 -->
	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name = "dataSource" ref="dataSource"></property>
	</bean>
	<!-- 2.xml配置事物的增强 -->
	<tx:advice id="txadvice" transaction-manager="transactionManager">
		<!-- 做事物操作 -->
		<tx:attributes>
			<!-- 设置进行事物操作的方法匹配规则 -->
			<tx:method name="account*"></tx:method>
			<tx:method name="insert*"></tx:method>
		</tx:attributes>
	</tx:advice>
	<!-- 3.xml配置切面 -->
	<aop:config >
		<!-- 切入点 -->
		<aop:pointcut expression="execution(* com.gog.tx.service.OrderService.*(..))" id="pointcut1"></aop:pointcut>
		<!-- 切面 -->
		<aop:advisor advice-ref="txadvice" pointcut-ref="pointcut1" ></aop:advisor>
	</aop:config>
	
	
	<bean id="orderUser" class="com.gog.tx.dao.OrderUser">
		<property name="jdbcTemplate" ref="jdbcTemplate"></property>
	</bean>
	<bean id="orderService" class="com.gog.tx.service.OrderService">
		<property name="orderUser" ref="orderUser"></property>
	</bean>

三: 事务的嵌套

通过上面的理论知识的铺垫,我们大致知道了数据库事务和spring事务的一些属性和特点,接下来我们通过分析一些嵌套事务的场景,来深入理解spring事务传播的机制。

假设外层事务 Service A 的 Method A() 调用 内层Service B 的 Method B()

PROPAGATION_REQUIRED(spring 默认)

如果ServiceB.methodB() 的事务级别定义为 PROPAGATION_REQUIRED,那么执行 ServiceA.methodA() 的时候spring已经起了事务,这时调用 ServiceB.methodB(),ServiceB.methodB() 看到自己已经运行在 ServiceA.methodA() 的事务内部,就不再起新的事务。

假如 ServiceB.methodB() 运行的时候发现自己没有在事务中,他就会为自己分配一个事务。

这样,在 ServiceA.methodA() 或者在 ServiceB.methodB() 内的任何地方出现异常,事务都会被回滚。

PROPAGATION_REQUIRES_NEW

比如我们设计 ServiceA.methodA() 的事务级别为 PROPAGATION_REQUIRED,ServiceB.methodB() 的事务级别为 PROPAGATION_REQUIRES_NEW。

那么当执行到 ServiceB.methodB() 的时候,ServiceA.methodA() 所在的事务就会挂起,ServiceB.methodB() 会起一个新的事务,等待 ServiceB.methodB() 的事务完成以后,它才继续执行。

他与 PROPAGATION_REQUIRED 的事务区别在于事务的回滚程度了。因为 ServiceB.methodB() 是新起一个事务,那么就是存在两个不同的事务。如果 ServiceB.methodB() 已经提交,那么 ServiceA.methodA() 失败回滚,ServiceB.methodB() 是不会回滚的。如果 ServiceB.methodB() 失败回滚,如果他抛出的异常被 ServiceA.methodA() 捕获,ServiceA.methodA() 事务仍然可能提交(主要看B抛出的异常是不是A会回滚的异常)。

PROPAGATION_SUPPORTS

假设ServiceB.methodB() 的事务级别为 PROPAGATION_SUPPORTS,那么当执行到ServiceB.methodB()时,如果发现ServiceA.methodA()已经开启了一个事务,则加入当前的事务,如果发现ServiceA.methodA()没有开启事务,则自己也不开启事务。这种时候,内部方法的事务性完全依赖于最外层的事务。

PROPAGATION_NESTED

现在的情况就变得比较复杂了, ServiceB.methodB() 的事务属性被配置为 PROPAGATION_NESTED, 此时两者之间又将如何协作呢?  ServiceB#methodB 如果 rollback, 那么内部事务(即 ServiceB#methodB) 将回滚到它执行前的 SavePoint 而外部事务(即 ServiceA#methodA) 可以有以下两种处理方式:

a、捕获异常,执行异常分支逻辑

void methodA() { 

        try { 

            ServiceB.methodB(); 

        } catch (SomeException) { 

            // 执行其他业务, 如 ServiceC.methodC(); 

        } 

    }

这种方式也是嵌套事务最有价值的地方, 它起到了分支执行的效果, 如果 ServiceB.methodB 失败, 那么执行 ServiceC.methodC(), 而 ServiceB.methodB 已经回滚到它执行之前的 SavePoint, 所以不会产生脏数据(相当于此方法从未执行过), 这种特性可以用在某些特殊的业务中, 而 PROPAGATION_REQUIRED 和 PROPAGATION_REQUIRES_NEW 都没有办法做到这一点。

b、 外部事务回滚/提交 代码不做任何修改, 那么如果内部事务(ServiceB#methodB) rollback, 那么首先 ServiceB.methodB 回滚到它执行之前的 SavePoint(在任何情况下都会如此), 外部事务(即 ServiceA#methodA) 将根据具体的配置决定自己是 commit 还是 rollback

//少钱的方法
	public void lessMoney(){
		String sql =" update account set salary=salary-? where id=?";
		int update = jdbcTemplate.update(sql,100,1);
		System.out.println(update);
		
		
		String sql2 = "SELECT * FROM account where ID = ?";
		Account account = jdbcTemplate.queryForObject(sql2, new MyAccount(),1);
		System.out.println(account);
	}
	//多钱方法
	public void moreMoney(){
		String sql =" update account set salary=salary+? where id=?";
		int update = jdbcTemplate.update(sql,100,2);
		System.out.println(update);
		
		
		String sql2 = "SELECT * FROM account where ID = ?";
		Account account = jdbcTemplate.queryForObject(sql2, new MyAccount(),2);
		System.out.println(account);
	}

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

JavaScript入门经典

JavaScript入门经典

Paul Wilton、Jeremy McPeak / 施宏斌 / 清华大学出版社 / 2009-2 / 98.00元

《Java Script入门经典(第3版)》首先介绍了J avaScript的基本语法,并介绍了如何发挥JavaScript中对象的威力。《Java Script入门经典(第3版)》还介绍了如何操纵最新版本浏览器所提供的BOM对象。在《Java Script入门经典(第3版)》的高级主题中,将介绍如何使用cookie,以及如何应用DHTML技术使Web页面焕发动感和活力。另外,《Java Scri......一起来看看 《JavaScript入门经典》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具