内容简介: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); }
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 数据库事物的四大特性(ACID)及事物隔离级别
- SpringBoot事物管理
- 事物分析和问题解决(200421)
- MySql 事物及隔离级别
- Redis 事物源码阅读:watch
- 你了解Spring事物控制特性吗
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
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入门经典》 这本书的介绍吧!