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);
	}

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

查看所有标签

猜你喜欢:

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

The Cult of the Amateur

The Cult of the Amateur

Andrew Keen / Crown Business / 2007-6-5 / USD 22.95

Amateur hour has arrived, and the audience is running the show In a hard-hitting and provocative polemic, Silicon Valley insider and pundit Andrew Keen exposes the grave consequences of today’s......一起来看看 《The Cult of the Amateur》 这本书的介绍吧!

MD5 加密
MD5 加密

MD5 加密工具

html转js在线工具
html转js在线工具

html转js在线工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换