基于Eclipse Maven的Spring4/Spring-MVC/Hibernate4整合之四:JdbcTemplate的事务管理
来源:互联网 发布:live for speed mac 编辑:程序博客网 时间:2024/05/16 12:44
JdbcTemplate自身是不具备事务功能的,而需要通过TransactionTemplate r的callback执行Jdbctemplate才能实现事务管理。
为了方便使用,我们可以自定义一个带有事务管理的TransJdbcTemplate类,通过注解方式注入了Spring数据库事务器 dsTm,此类提供了事务执行方法doTransactionBatch:
package com.freestyle.common.spring;import javax.annotation.Resource;import javax.sql.DataSource;import org.springframework.context.annotation.DependsOn;import org.springframework.jdbc.core.JdbcTemplate;import org.springframework.transaction.TransactionStatus;import org.springframework.transaction.support.TransactionCallback;import org.springframework.transaction.support.TransactionTemplate;/**** * 带有事务管理的JdbcTemplate * @author dgmislrh * */@DependsOn({"dsTransactionManager"})//@Repository("transJdbcTemplate")public class TransJdbcTemplate extends org.springframework.jdbc.core.JdbcTemplate{@Resource(name="dsTransactionManager")private org.springframework.jdbc.datasource.DataSourceTransactionManager dsTm;public static interface TransCallback{public void onExecute(JdbcTemplate pvJt);}public TransJdbcTemplate(DataSource dataSource) {super (dataSource);}/**** * 若需要回滚事务,在onExecute里面throw runtimeexception即可 * @param lvCallback */public void doTransactionBatch(final TransCallback lvCallback){TransactionTemplate lvTt=new TransactionTemplate (dsTm);lvTt.execute(new TransactionCallback<Boolean>() {@Overridepublic Boolean doInTransaction(TransactionStatus arg0) {JdbcTemplate lvJt=(JdbcTemplate) ContextHolder.getBean("jdbcTemplate");lvCallback.onExecute(lvJt);return true;}});}}
然后打开spring-db.xml,在里面配置这个类和spring的数据库事务管理器:
<bean id="dsTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean> <!-- 配置具备事务管理的Jdbc Template --> <bean id="transJdbcTemplate" class="com.freestyle.common.spring.TransJdbcTemplate" > <constructor-arg ref="dataSource"></constructor-arg></bean>
public class HibernateController implements org.springframework.web.servlet.mvc.Controller {// @Resource(name="hibernateUserDao")// private HibernateUserDao lvDao;// @Resource(name="hibernateUserDao")@Resource(name = "hibernateUserDao")protected IHibernateEntityDao<TaUser> mvDao;@Resource(name = "hUserBaseDao")protected IHibernateEntityDao<TaUser> mvBaseDao;@RequestMapping("/test")public ModelAndView test(@RequestParam(value = "name", defaultValue = "World") final String name)throws SQLException {System.out.println("Hello " + name);Map<String, Object> lvMap = new HashMap<String, Object>();/* * TaUser lvUser= lvDao.getUser("dgmislrh"); if (lvUser!=null){ * System.out.println(lvUser.getFaName()); } */StringBuilder lvSb = new StringBuilder();TransJdbcTemplate lvJt = (TransJdbcTemplate) ContextHolder.getBean("transJdbcTemplate");lvJt.doTransactionBatch(new TransCallback() {@Overridepublic void onExecute(JdbcTemplate pvJt) {pvJt.update("update ta_user set fa_name='new value' where fa_login=?", new PreparedStatementSetter() {@Overridepublic void setValues(PreparedStatement ps) throws SQLException {ps.setString(1, name);}});}});lvSb.append("成功设置fa_name为new value.<br/>");// case 1: 程序错误导致回滚,保证了数据完整性try {lvJt.doTransactionBatch(new TransCallback() {@Overridepublic void onExecute(JdbcTemplate pvJt) {// 第一条SQL成功执行pvJt.update("update ta_user set fa_name='new value 1' where fa_login=?",new PreparedStatementSetter() {@Overridepublic void setValues(PreparedStatement ps) throws SQLException {ps.setString(1, name);}});// 第二条SQL语法错误,会导致上面的执行结果无效(事务回滚)pvJt.update("la la update ta_user set fa_name='new value 2' where fa_login=?",new PreparedStatementSetter() {@Overridepublic void setValues(PreparedStatement ps) throws SQLException {ps.setString(1, name);}});}});} catch (Exception e) {lvSb.append("执行错误:" + e.getMessage() + "<br/>");}// case 2: 根据需要用抛出exception方式触发,回滚try {lvJt.doTransactionBatch(new TransCallback() {@Overridepublic void onExecute(JdbcTemplate pvJt) {// 第一条SQL成功执行pvJt.update("update ta_user set fa_name='new value 3' where fa_login=?",new PreparedStatementSetter() {@Overridepublic void setValues(PreparedStatement ps) throws SQLException {ps.setString(1, name);}});if (pvJt != null) { // 模拟事后的业务检查失败,抛出exception以回滚throw new RuntimeException("我长得太帅,不通过<br/>");}}});} catch (Exception e) {lvSb.append("业务检查不通过:" + e.getMessage());}TaUser lvUser = mvDao.get(name);lvSb.append("最后fa_name的值为"+lvUser.getFaName());lvMap.put("result", lvSb.toString());/* * TaUser lvUser=mvDao.get(name); lvUser.setFaName("new name 22222"); * mvBaseDao.save(lvUser); lvUser=mvDao.get(name); if (lvUser!=null){ * System.out.println(lvUser.getFaName()); lvMap.put("result", * lvUser.getFaName()); } */return new ModelAndView("/result", lvMap);}
启动tomcat,在浏览器地址栏输入http://localhost/gpchat/hibernate/test?name=dgmislrh,网页显示:
成功设置fa_name为new value.执行错误:PreparedStatementCallback; bad SQL grammar [la la update ta_user set fa_name='new value 2' where fa_login=?]; nested exception is org.postgresql.util.PSQLException: ERROR: syntax error at or near "la" 位置:1业务检查不通过:我长得太帅,不通过最后fa_name的值为new value
0 0
- 基于Eclipse Maven的Spring4/Spring-MVC/Hibernate4整合之四:JdbcTemplate的事务管理
- 基于Eclipse Maven的Spring4/Spring-MVC/Hibernate4整合之五:Hibernate的事务管理、手动回滚
- 基于Eclipse Maven的Spring4/Spring-MVC/Hibernate4整合之三:hibernate4泛型dao的应用
- 基于Eclipse Maven的Spring4/Spring-MVC/Hibernate4整合之六:Hibernate的flush和clear
- 基于Eclipse Maven的Spring4/Spring-MVC/Hibernate4整合之十:Spring mvc & hibernate 事务处理(回滚)
- 基于Eclipse Maven的Spring4/Spring-MVC/Hibernate4整合之二: Spring/proxool数据源/Hibernate的配置
- 基于Eclipse Maven的Spring4/Spring-MVC/Hibernate4整合之七:Hibernate Entity的多字段组成主键处理
- 基于Eclipse Maven的Spring4/Spring-MVC/Hibernate4整合之十二: hibernate利用PostgreSQL自带的SEQUENCE生成主键
- 基于Eclipse Maven的Spring4/Spring-MVC/Hibernate4整合之十四:hibernate关于缓冲机制的巨坑!
- 基于Eclipse Maven的Spring4/Spring-MVC/Hibernate4整合之十一:利用拦截器控制访问权限
- 基于Eclipse Maven的Spring4/Spring-MVC/Hibernate4整合之一 : Maven的pom.xml环境配置及注意方面
- 基于Eclipse Maven的Spring4/Spring-MVC/Hibernate4整合之八:一个简单例子演示Spring-MVC中多种参数传递方式
- 基于Eclipse Maven的Spring4/Spring-MVC/Hibernate4整合之十三:用Spring嵌套事务(Nested Transaction) 回滚并返回自定义Exception
- 基于Eclipse Maven的Spring4/Spring-MVC/Hibernate4整合之九:Hibernate Session Helper类,用于Entity属性与表字段的操作...
- spring4 hibernate4 struts2 maven的整合
- Eclipse+Struts2+Hibernate4+Spring4的整合
- Spring MVC的事务配置和Spring4与Hibernate4的整合
- Spring4+Hibernate4+SpringMVC的整合
- handler.obtainMessage()与Message.obtain()的区别
- EMACS学习笔记
- Glide入门简介
- RunTime 应用实例–关于埋点的思考
- 模式识别(Pattern Recognition)学习笔记(三十一)-- 线性回归
- 基于Eclipse Maven的Spring4/Spring-MVC/Hibernate4整合之四:JdbcTemplate的事务管理
- linux 复制时保留文件的目录结构
- ElasticSearch学习三:搜索实例含高亮显示及搜索的特殊字符过滤
- 13. Roman to Integer
- 运维团队能从橄榄球教练身上学到什么(节选)
- 注解机制及其原理
- 理解c语言中的void*用法
- hbase学习笔记
- Dalvik(达尔维克)和ART的区别