spring可以支持编程式事务和声明式事务。

Spring使用事务管理器,每个不同平台的事务管理器都实现了接口:PlatformTransactionManager

此接口是事务管理的核心,提供了三个需要实现的函数:

[java] view plaincopy print?
  1. commit(TransactionStatus status) ;
  2. getTransaction(TransactionDefinition definition) ;
  3. rollback(TransactionStatus status) ;

如果我们使用的是JDBC来处理事务,那么这个事务管理器就是DataSourceTransactionManager。

通过Spring文档查找到这个类,发现其需要DataSource这个类。也就是只要实现了javax.sql.DataSource这个接口的类,都可以作为参数传入到DataSourceTransactionManager。

然后,找到 包org.springframework.transaction.support中的 TransactionTemplate。

发现TransactionTemplate中有一个重要的方法:

[java] view plaincopy print?
  1. execute(TransactionCallback action) ;

就是利用这个方法,我们可以在这个方法中添加事务。

这个方法需要传入参数 TransactionCallback。

TransactionCallback,顾名思义,就是事务回调然后查到TransactionCallback。

发现这是一个接口(这也必须是接口,因为任务都是自己具体定义的)

里面只有一个方法:

[java] view plaincopy print?
  1. doInTransaction(TransactionStatus status) ;

很明显,就是在一个事务中需要做的事情都包括这这个方法中了。

而这个doInTransaction 又传入了一个参数,这次是 TransactionStatus,继续顾名思义,也就是事务状态。

查询下去,这个 TransactionStatus 还是一个接口。 看看这个接口定义了哪些服务(方法):

[java] view plaincopy print?
  1. hasSavepoint() ;
  2. isCompleted() ;
  3. isNewTransaction() ;
  4. setRollbackOnly() ;

当需要回滚的时候,需要在调用 setRoolbackOnly(); 就OK了。

好了,走了这么久,现在就来简单总结一下编程式事务管理。

首先: 因为我们使用的是特定的平台,所以,我们需要创建一个合适我们的平台事务管理PlateformTransactionManager。如果使用的是JDBC的话,就用DataSourceTransactionManager。注意需要传入一个DataSource,这样,平台才知道如何和数据库打交道。

第二: 为了使得平台事务管理器对我们来说是透明的,就需要使用 TransactionTemplate。使用TransactionTemplat需要传入一个 PlateformTransactionManager 进入,这样,我们就得到了一个 TransactionTemplate,而不用关心到底使用的是什么平台了。

第三: TransactionTemplate 的重要方法就是 execute 方法,此方法就是调用 TransactionCallback 进行处理。

也就是说,实际上我们需要处理的事情全部都是在 TransactionCallback 中编码的。

第四: 也就是 TransactionCallback 接口,我们可以定义一个类并实现此接口,然后作为 TransactionTemplate.execute 的参数。把需要完成的事情放到 doInTransaction中,并且传入一个 TransactionStatus 参数。此参数是来调用回滚的。

也就是说 ,PlateformTransactionManager 和 TransactionTemplate 只需在程序中定义一次,而TransactionCallback 和 TransactionStatus 就要针对不同的任务多次定义了。

这就是Spring的编程式事务管理。下面贴出例子代码:

TemplateUtils

[java] view plaincopy print?
  1. import javax.naming.Context;
  2. import javax.naming.InitialContext;
  3. import javax.naming.NamingException;
  4. import javax.sql.DataSource;
  5. import org.apache.log4j.Logger;
  6. import org.springframework.jdbc.core.JdbcTemplate;
  7. import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
  8. import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
  9. import org.springframework.jdbc.datasource.DataSourceTransactionManager;
  10. import org.springframework.transaction.PlatformTransactionManager;
  11. import org.springframework.transaction.support.TransactionTemplate;
  12. public class TemplateUtils {
  13. private static Logger logger = Logger.getLogger(TemplateUtils.class);
  14. private static String oracleDS = "<a href="http://lib.csdn.net/base/17" class='replace_word' title="Java EE知识库" target='_blank' style='color:#df3434; font-weight:bold;'>Java</a>:OracleDS";
  15. private static DataSource dataSource = null;
  16. static {
  17. try {
  18. Context context = new InitialContext();
  19. dataSource = (DataSource) context.lookup(oracleDS);
  20. } catch (NamingException e) {
  21. logger.info("查找数据源失败···", e);
  22. }
  23. }
  24. public static TransactionTemplate getTransactionTemplate() {
  25. PlatformTransactionManager txManager = new DataSourceTransactionManager(
  26. dataSource);
  27. return new TransactionTemplate(txManager);
  28. }
  29. public static JdbcTemplate getJdbcTemplate() {
  30. return new JdbcTemplate(dataSource);
  31. }
  32. public static NamedParameterJdbcTemplate getNamedParameterJdbcTemplate() {
  33. return new NamedParameterJdbcTemplate(dataSource);
  34. }
  35. public static SimpleJdbcTemplate getSimpleJdbcTemplate() {
  36. return new SimpleJdbcTemplate(dataSource);
  37. }
  38. }

Test

[java] view plaincopy print?
  1. import javax.naming.Context;
  2. import javax.naming.InitialContext;
  3. import javax.sql.DataSource;
  4. import org.springframework.jdbc.core.JdbcTemplate;
  5. import org.springframework.jdbc.datasource.DataSourceTransactionManager;
  6. import org.springframework.transaction.PlatformTransactionManager;
  7. import org.springframework.transaction.TransactionStatus;
  8. import org.springframework.transaction.support.DefaultTransactionDefinition;
  9. import org.springframework.transaction.support.TransactionCallback;
  10. import org.springframework.transaction.support.TransactionCallbackWithoutResult;
  11. import org.springframework.transaction.support.TransactionTemplate;
  12. @SuppressWarnings("all")
  13. public class Test {
  14. public void m1() throws Exception {
  15. TransactionTemplate transactionTemplate = TemplateUtils
  16. .getTransactionTemplate();
  17. Object object = transactionTemplate.execute(new TransactionCallback() {
  18. public Object doInTransaction(TransactionStatus status) {
  19. try {
  20. // 数据库操作1
  21. // 数据库操作2
  22. } catch (Exception e) {
  23. status.setRollbackOnly();
  24. e.printStackTrace();
  25. }
  26. return null;
  27. }
  28. });
  29. }
  30. public void m2() throws Exception {
  31. TransactionTemplate transactionTemplate = TemplateUtils
  32. .getTransactionTemplate();
  33. transactionTemplate.execute(new TransactionCallbackWithoutResult() {
  34. protected void doInTransactionWithoutResult(TransactionStatus s) {
  35. try {
  36. // 数据库操作1
  37. // 数据库操作2
  38. } catch (Exception e) {
  39. s.setRollbackOnly();
  40. e.printStackTrace();
  41. }
  42. }
  43. });
  44. }
  45. public void m3() throws Exception {
  46. Context ctx = new InitialContext();
  47. DataSource ds = (DataSource) ctx.lookup("java:OracleDS");
  48. JdbcTemplate jt = new JdbcTemplate(ds);
  49. DefaultTransactionDefinition tf = new DefaultTransactionDefinition();
  50. PlatformTransactionManager tm = new DataSourceTransactionManager(ds);
  51. TransactionStatus ts = tm.getTransaction(tf);
  52. try {
  53. // 数据库操作1
  54. // 数据库操作2
  55. tm.commit(ts);
  56. } catch (Exception e) {
  57. tm.rollback(ts);
  58. e.printStackTrace();
  59. }
  60. }
  61. }

JdbcUtils

[java] view plaincopy print?
  1. import java.sql.CallableStatement;
  2. import java.sql.Connection;
  3. import java.sql.PreparedStatement;
  4. import java.sql.ResultSet;
  5. import java.sql.SQLException;
  6. import java.sql.Savepoint;
  7. import javax.naming.Context;
  8. import javax.naming.InitialContext;
  9. import javax.naming.NamingException;
  10. import javax.sql.DataSource;
  11. import org.apache.log4j.Logger;
  12. public class JdbcUtils {
  13. private static Logger logger = Logger.getLogger(JdbcUtils.class);
  14. private static String oracleDS = "java:OracleDS";
  15. private static DataSource dataSource = null;
  16. static {
  17. try {
  18. Context context = new InitialContext();
  19. dataSource = (DataSource) context.lookup(oracleDS);
  20. } catch (NamingException e) {
  21. logger.info("查找数据源失败···", e);
  22. }
  23. }
  24. public static Connection getConnection() {
  25. Connection conn = null;
  26. try {
  27. conn = dataSource.getConnection();
  28. } catch (SQLException e) {
  29. logger.info("获取数据库连接失败···", e);
  30. }
  31. return conn;
  32. }
  33. public static void close(Connection conn) {
  34. if (conn != null) {
  35. try {
  36. conn.close();
  37. } catch (SQLException e) {
  38. logger.info("释放数据库连接失败···", e);
  39. }
  40. }
  41. }
  42. public static void close(CallableStatement cs) {
  43. if (cs != null) {
  44. try {
  45. cs.close();
  46. } catch (SQLException e) {
  47. logger.info("关闭CallableStatement失败···", e);
  48. }
  49. }
  50. }
  51. public static void close(PreparedStatement ps) {
  52. if (ps != null) {
  53. try {
  54. ps.close();
  55. } catch (SQLException e) {
  56. logger.info("关闭PreparedStatement失败···", e);
  57. }
  58. }
  59. }
  60. public static void close(ResultSet rs) {
  61. if (rs != null) {
  62. try {
  63. rs.close();
  64. } catch (SQLException e) {
  65. logger.info("关闭ResultSet失败···", e);
  66. }
  67. }
  68. }
  69. public static void setAutoCommit(Connection conn, boolean autoCommit) {
  70. if (conn != null) {
  71. try {
  72. conn.setAutoCommit(autoCommit);
  73. } catch (SQLException e) {
  74. logger.info("设置事务提交方式失败···", e);
  75. }
  76. }
  77. }
  78. public static void commit(Connection conn) {
  79. if (conn != null) {
  80. try {
  81. conn.commit();
  82. } catch (SQLException e) {
  83. logger.info("提交事务失败···", e);
  84. }
  85. }
  86. }
  87. public static void rollback(Connection conn) {
  88. if (conn != null) {
  89. try {
  90. conn.rollback();
  91. } catch (SQLException e) {
  92. logger.info("回滚事务失败···", e);
  93. }
  94. }
  95. }
  96. public static void rollback(Connection conn, Savepoint sp) {
  97. if (conn != null) {
  98. try {
  99. conn.rollback(sp);
  100. } catch (SQLException e) {
  101. logger.info("回滚事务失败···", e);
  102. }
  103. }
  104. }
  105. }

springmvc事务管理详解相关推荐

  1. Spring事务管理详解_基本原理_事务管理方式

    Spring事务管理详解_基本原理_事务管理方式 1. 事务的基本原理 Spring事务的本质其实就是数据库对事务的支持,使用JDBC的事务管理机制,就是利用java.sql.Connection对象 ...

  2. 关于事务管理的理解和Spring事务管理详解

    转载于:http://www.mamicode.com/info-detail-1248286.html 1 初步理解 理解事务之前,先讲一个你日常生活中最常干的事:取钱. 比如你去ATM机取1000 ...

  3. Spring事务管理详解

    什么是事务 事务是逻辑上的一组操作,要么都执行,要么都不执行. 需要注意的是:事务能否生效数据库引擎是否支持事务是关键.比如常用的 MySQL 数据库默认使用支持事务的 innodb引擎.但是,如果把 ...

  4. Spring Boot事务管理详解

    什么是事务? 我们在开发企业应用时,对于业务人员的一个操作实际是对数据读写的多步操作的结合.由于数据操作在顺序执行的过程中,任何一步操作都有可能发生异常,异常会导致后续操作无法完成,此时由于业务逻辑并 ...

  5. 什么是事务的传播_这么漂亮的Spring事务管理详解,你不来看看?

    事务概念回顾 什么是事务? 事务是逻辑上的一组操作,要么都执行,要么都不执行. 事物的特性(ACID): 原子性: 事务是最小的执行单位,不允许分割.事务的原子性确保动作要么全部完成,要么完全不起作用 ...

  6. Spring中的事务管理详解

    在这里主要介绍Spring对事务管理的一些理论知识,实战方面参考上一篇博文: http://www.cnblogs.com/longshiyVip/p/5061547.html 1. 事务简介: 事务 ...

  7. Java程序员从笨鸟到菜鸟之(八十)细谈Spring(九)spring+hibernate声明式事务管理详解

    声明式事务管理是spring对事务管理的最常用的方式,因为这种方式对代码的影响最小,因此也符合非侵入性的轻量级容器的概念.Spring的事务管理是通过AOP的方式来实现的,因为事务方面的代码与spri ...

  8. 多数据源 事务管理_可能是最漂亮的Spring事务管理详解

    事务概念回顾 什么是事务? 事务是逻辑上的一组操作,要么都执行,要么都不执行. 事物的特性(ACID): 原子性: 事务是最小的执行单位,不允许分割.事务的原子性确保动作要么全部完成,要么完全不起作用 ...

  9. spring事务管理器的作用_【面试必问】Spring中的事务管理详解

    在这里主要介绍Spring对事务管理的一些理论知识,实战方面参考上一篇博文: http://www.cnblogs.com/longshiyVip/p/5061547.html 1. 事务简介: 事务 ...

最新文章

  1. Oracle 11g 预定义账户和PLSQL工具、企业管理器的初步使用
  2. Java Web(五) JSP详解(四大作用域九大内置对象等)
  3. Fedora 27安装vim插件YouCompleteMe
  4. mysql账号相关的操作和安全管理
  5. redis压缩列表ziplist的连锁扩容
  6. php与web页面交互
  7. 【第2重磅】王者荣耀「绝悟」升级,全英雄池解禁
  8. (最全干货分享)渗透测试全流程归纳总结之四
  9. 随笔 2021-11-23
  10. Dell PowerEdge R750 Intel DAOS 顺利通过“HighPerf Ready 1.0”测试
  11. pycharm IDEA专业版2016.3.2版本和 python3.5.0 win7 64位安装包 百度云资源共享 及安装和编辑器注册图录
  12. 3月12日公开短线黑马牛股请点击验证
  13. 微信 进入公众号获取地理位置
  14. EasyNVR摄像头网页无插件直播H5、谷歌Chrome直播方案中如何降低播放延迟问题
  15. 搭建ipv6有状态dhcp服务器,思科IPv6技术 IPv6有状态自动配置地址
  16. 计算机网络实验(思科模拟器Cisco Packet Tracer)配置静态路由使三台pc机网络互通
  17. 新款文章,绝无仅有!微信语音aud文件转换为mp3格式
  18. 网易《大唐》产品经理赵青采访
  19. IPv6来啦 (by quqi99)
  20. 计算机病毒生命周期,计算机病毒的生命周期 -电脑资料

热门文章

  1. 埃及旅游游记: 欣赏世界最古老的纸画
  2. int向下取整/向上取整
  3. Vue导出页面为word格式
  4. 02_python数据分析之matplotlib
  5. 消息队列MQ的使用场景
  6. html 共享文件夹,手把手教你win7系统怎么共享文件夹
  7. redis集群方案-Twemproxy
  8. javascript函数以及对象
  9. launchAnyWhere: Activity组件权限绕过漏洞解析
  10. 【项目管理】对管理的认识与思考