【Spring 事务管理系列之一】Spring使用JDBC的事务管理例子
2015-01-10 18:11
375 查看
本打算系列之一把这次写的大纲列出来呢,无奈自己没想好,只有大致定一个方向,待后面补充,或者重新组织这一系列。
做几个概念的澄清和一些基础东西的介绍
1、假设你熟悉JDBC提供的api操作,比如:
JDBC提供的事务处理API非常少,请不要被Spring中事务处理的那一堆源代码所打击得信心尽失,这些框架提供的事务处理功能归根结底主要通过以Connection类的方法完成:
2、本地事务和分布式事务
本地(Local Transaction)事务指只有一个数据源参与的事务,比如只有数据库或者只有JMS;分布式事务(Distributed Transaction)指有多个数据源同时参与的事务,比如一项操作需要同时访问数据库和通过JMS发送消息,或者一项操作需要同时访问两个不同数据库。对于分布式事务,Java提供了JTA规范,它的原理与本地事务存在不同。 鉴于多数情况下Java事务为本地事务。
3、线程安全的基础
为什么会扯到线程安全呢,因为一次DB的连接是Connection对象决定的,同一个Connection对象,有可能会同事被多个Thread访问,同时了解ThreadLocal【1】来解决多线程之间的共享问题。
4、Spring 事务管理系列之一(JDBC的事务管理例子)
这个是开篇,通过这个系列一,会直观的展示一下事务,给刚接触的同学一点直观的感知,当然可能有自己理解不当的地方,也请大牛指出。
本文将使用两张表来演示事务的处理过程,怎么来证明事务在执行了呢?一般情况下是save之后数据库db能看得到,但是这不能证明事务起作用了,这个例子中会通过使用插入一张customer表,一张Address表,在插入customer表之后,抛出异常,在插入address表,这两个操作是放在一个事务里面的,如果最后表里面没有数据,则表明,事务确实起作用啦,要么全插,要么不插。
4.1、创建database
customer.sql
address.sql
数据库表结构:
4.2、项目使用maven进行管理,由于本项目使用jdbc连接mysql,所以包含mysql-connector-java,spring-tx,因为要实用JDBCTemplate所以又包括spring-jdbc其他依赖如下:
4.3、具体实现
关于spring.xml bean的配置,还有pojo的配置不多做介绍。主要提出来事务处理的逻辑:
可见,customer表插入之后,打印“Inserted into Customer Table Successfully”然后再插入Address那张表,我们在设计Address这张表的时候要求Address的地址字段是小于20 chars的长度,我们在测试代码里面故意构造,大于20的长度,让其抛出异常,代码如下:
运行结果:
同时查看,数据库发现customer表中,并无数据,符合预期,表明事务生效啦。
5、问题和思考?
spring是如何实现事务管理的呢?下面几篇文章,会实现一个很简单的类似spring事务管理的功能。
代码下载
做几个概念的澄清和一些基础东西的介绍
1、假设你熟悉JDBC提供的api操作,比如:
JDBC提供的事务处理API非常少,请不要被Spring中事务处理的那一堆源代码所打击得信心尽失,这些框架提供的事务处理功能归根结底主要通过以Connection类的方法完成:
Connection.setAutoCommit(boolean); Connection.commit(); Connection.rollback();
2、本地事务和分布式事务
本地(Local Transaction)事务指只有一个数据源参与的事务,比如只有数据库或者只有JMS;分布式事务(Distributed Transaction)指有多个数据源同时参与的事务,比如一项操作需要同时访问数据库和通过JMS发送消息,或者一项操作需要同时访问两个不同数据库。对于分布式事务,Java提供了JTA规范,它的原理与本地事务存在不同。 鉴于多数情况下Java事务为本地事务。
3、线程安全的基础
为什么会扯到线程安全呢,因为一次DB的连接是Connection对象决定的,同一个Connection对象,有可能会同事被多个Thread访问,同时了解ThreadLocal【1】来解决多线程之间的共享问题。
4、Spring 事务管理系列之一(JDBC的事务管理例子)
这个是开篇,通过这个系列一,会直观的展示一下事务,给刚接触的同学一点直观的感知,当然可能有自己理解不当的地方,也请大牛指出。
本文将使用两张表来演示事务的处理过程,怎么来证明事务在执行了呢?一般情况下是save之后数据库db能看得到,但是这不能证明事务起作用了,这个例子中会通过使用插入一张customer表,一张Address表,在插入customer表之后,抛出异常,在插入address表,这两个操作是放在一个事务里面的,如果最后表里面没有数据,则表明,事务确实起作用啦,要么全插,要么不插。
4.1、创建database
customer.sql
CREATE TABLE `Customer` ( `id` int(11) unsigned NOT NULL, `name` varchar(20) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
address.sql
CREATE TABLE `Address` ( `id` int(11) unsigned NOT NULL, `address` varchar(20) DEFAULT NULL, `country` varchar(20) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
数据库表结构:
4.2、项目使用maven进行管理,由于本项目使用jdbc连接mysql,所以包含mysql-connector-java,spring-tx,因为要实用JDBCTemplate所以又包括spring-jdbc其他依赖如下:
<properties> <!-- Generic properties --> <java.version>1.6</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <!-- Spring --> <spring-framework.version>3.0.6.RELEASE</spring-framework.version> <!-- Logging --> <logback.version>1.0.13</logback.version> <slf4j.version>1.7.5</slf4j.version> <!-- Test --> <junit.version>4.11</junit.version> </properties> <dependencies> <!-- Spring and Transactions --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring-framework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>${spring-framework.version}</version> </dependency> <dependency> <groupId>cglib</groupId> <artifactId>cglib-nodep</artifactId> <version>3.1</version> </dependency> <!-- Spring JDBC and MySQL Driver --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${spring-framework.version}</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.0.5</version> </dependency> <!-- Logging with SLF4J & LogBack --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>${slf4j.version}</version> <scope>compile</scope> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>${logback.version}</version> <scope>runtime</scope> </dependency> <!-- Test Artifacts --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${spring-framework.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>${junit.version}</version> <scope>test</scope> </dependency> </dependencies>
4.3、具体实现
关于spring.xml bean的配置,还有pojo的配置不多做介绍。主要提出来事务处理的逻辑:
public void create(Customer customer) { String queryCustomer = "insert into Customer (id, name) values (?,?)"; String queryAddress = "insert into Address (id, address,country) values (?,?,?)"; JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); jdbcTemplate.update(queryCustomer, new Object[] { customer.getId(), customer.getName() }); System.out.println("Inserted into Customer Table Successfully"); jdbcTemplate.update(queryAddress, new Object[] { customer.getId(), customer.getAddress().getAddress(), customer.getAddress().getCountry() }); System.out.println("Inserted into Address Table Successfully"); }
可见,customer表插入之后,打印“Inserted into Customer Table Successfully”然后再插入Address那张表,我们在设计Address这张表的时候要求Address的地址字段是小于20 chars的长度,我们在测试代码里面故意构造,大于20的长度,让其抛出异常,代码如下:
Customer customer = new Customer(); customer.setId(2); customer.setName("lianzi"); Address address = new Address(); address.setId(2); address.setCountry("china"); // setting value more than 20 chars, so that SQLException occurs address.setAddress("********************************************"); customer.setAddress(address); return customer;
运行结果:
同时查看,数据库发现customer表中,并无数据,符合预期,表明事务生效啦。
5、问题和思考?
spring是如何实现事务管理的呢?下面几篇文章,会实现一个很简单的类似spring事务管理的功能。
代码下载
相关文章推荐
- 【Java EE 学习 52】【Spring学习第四天】【Spring与JDBC】【JdbcTemplate创建的三种方式】【Spring事务管理】【事务中使用dbutils则回滚失败!!!??】
- hibernate,spring管理事务中(transaction,JDBC connection,Hibernate Session的使用)
- Spring JDBC使用、事务管理
- Spring-jdbc:事务管理器的使用
- JSP Web开发入门系列(二)---JDBC事务管理
- 使用Spring 2.0 新特性实现声明式事务管理-基于Annotation
- Spring使用XML进行声明式的事务管理
- spring中JDBC 声明式事务管理
- Spring 下事务管理 - 使用 AOP XML 配置管理(iBatis 为例)
- Spring 使用Spring注解方式管理事务与传播行为
- 学习笔记---------------------spring2.5+jdbc(jdbctemplate)+事务管理
- Spring2.0简明手册(系列之五 事务管理)
- Spring下,使用BeanNameAutoProxyCreator来管理Transaction例子
- spring对hibernate提供的事务管理的一个实用的例子
- Spring 下事务管理-使用AOP @Transactional注解管理
- 《Spring 2.0技术手册》 读书笔记七-Spring的DAO框架(3)-JDBC事务管理
- 使用spring管理事务的时候,配置文件的主意事项。
- Spring视频学习(九)使用Spring注解方式管理事务与传播行为详解
- Spring集成的jdbc编码和事务管理
- 使用Spring注解方式管理事务与传播行为详解