JavaEE学习之Spring声明式事务

一、引言

上一篇文章,学习了AOP相关知识,并做了一个简单的Hello world。本文在上篇文章的基础上,进一步学习下Spring的声明式事务。

二、相关概念

1. 事务(Transaction)——它是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位

2. 事务的几大特性(A、C、I、D):

  A——Atomicity(原子性)。数据库中的事务执行是作为原子。即不可再分,整个语句要么执行,要么不执行。

  C——Consistency(一致性)。在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏。

  I——Isolation(隔离性)。事务的执行是互不干扰的,一个事务不可能看到其他事务运行时,中间某一时刻的数据。

  D——Durability(持久性)。事务完成后,对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。

3.spring中事务有以下5中属性:

  (1)传播行为。即事务的传递,例如:

     PROPAGATION_MANDATORY:该方法必须运行在一个事务中。如果当前事务不存在则抛出异常。

     PROPAGATION_NEVER:当前方法不应该运行在一个事务中。如果当前存在一个事务,则抛出异常.

     PROPAGATION_REQUIRED:该方法必须运行在一个事务中。如果一个事务正在运行,该方法将运行在这个事务中。否则,就开始一个新的事务。

     ...

  (2)隔离级别。多个事务并发执行,会产生脏读,不可重复读,幻读等问题,为避免这些问题,常常会设置隔离级别

  (3)只读。主要用于优化

  (4)超时。释放资源

  (5)回滚规则。

4.多个事务并发运行,产生的问题:

  (1)脏读(Dirty read)。当事务读取还未被提交的数据时。(读未提交)

  (2)不可重复读(Nonrepeatable read)。同一个事务中两次读取同一数据,每次得到的数据都不一样。(读不回去,其他事务是更新操作)

  (3)幻读(Phantom read)。一个事务在进行相同条件的两次或两次以上查询,结果在稍后的相同条件的查询中读取的结果不一样,会发现原来没有的记录。(读多了,其他事务是插入操作)

5.隔离级别:

  (1)读未提交(Read Uncommitted,ansi sql值:1 ).允许脏读取,但不允许更新丢失。

  (2)读已提交(Read Committed,ansi sql值:2 ).允许不可重复度,但不允许脏读取。

  (3)可以重复读(Repeatable Read,ansi sql值:4 ).禁止不可重复读和脏读取,但是有时可能出现幻影数据。

  (4)串行化(Serializable,ansi sql值:8 ).提供严格的事务隔离。它要求事务序列化执行,不支持并发。

6.spring的事务机制主要有两种:编程式事务和声明式事务。

  编程式事务:所谓编程式事务指的是通过编码方式实现事务,即类似于JDBC编程实现事务管理。

  声明式事务:在Spring中,主要是通过AOP来完成声明式的事务管理。

三、实例

1.建库建表。使用MySQL新建TEST库,然后新建CUSTOMER表。脚本如下:

1 CREATE TABLE `customer` (
2   `RECID` int(10) NOT NULL AUTO_INCREMENT,
3   `NAME` varchar(100) NOT NULL,
4   `AGE` int(3) NOT NULL,
5   PRIMARY KEY (`RECID`)
6 )

2.新建项目,并引入相关jar包

项目结构:

pom.xml:

  1 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  2     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  3     <modelVersion>4.0.0</modelVersion>
  4     <groupId>com.wzhang</groupId>
  5     <artifactId>spring-demo</artifactId>
  6     <packaging>war</packaging>
  7     <version>0.0.1-SNAPSHOT</version>
  8     <name>spring-demo Maven Webapp</name>
  9     <url>http://maven.apache.org</url>
 10     <properties>
 11         <junit.version>3.8.1</junit.version>
 12         <log4j.version>1.2.17</log4j.version>
 13         <javax.servlet.version>2.5</javax.servlet.version>
 14         <org.hibernate.version>4.1.7.Final</org.hibernate.version>
 15         <org.springframework.version>3.2.3.RELEASE</org.springframework.version>
 16         <org.apache.struts.version>2.3.16.3</org.apache.struts.version>
 17     </properties>
 18     <dependencies>
 19         <dependency>
 20             <groupId>junit</groupId>
 21             <artifactId>junit</artifactId>
 22             <version>${junit.version}</version>
 23             <scope>test</scope>
 24         </dependency>
 25         <dependency>
 26             <groupId>javax.servlet</groupId>
 27             <artifactId>servlet-api</artifactId>
 28             <version>${javax.servlet.version}</version>
 29         </dependency>
 30         <!-- Spring -->
 31         <dependency>
 32             <groupId>org.springframework</groupId>
 33             <artifactId>spring-beans</artifactId>
 34             <version>${org.springframework.version}</version>
 35         </dependency>
 36         <dependency>
 37             <groupId>org.springframework</groupId>
 38             <artifactId>spring-context</artifactId>
 39             <version>${org.springframework.version}</version>
 40         </dependency>
 41         <dependency>
 42             <groupId>org.springframework</groupId>
 43             <artifactId>spring-core</artifactId>
 44             <version>${org.springframework.version}</version>
 45         </dependency>
 46
 47         <dependency>
 48             <groupId>org.springframework</groupId>
 49             <artifactId>spring-web</artifactId>
 50             <version>${org.springframework.version}</version>
 51         </dependency>
 52         <dependency>
 53             <groupId>org.springframework</groupId>
 54             <artifactId>spring-expression</artifactId>
 55             <version>${org.springframework.version}</version>
 56         </dependency>
 57         <dependency>
 58             <groupId>org.springframework</groupId>
 59             <artifactId>spring-aop</artifactId>
 60             <version>${org.springframework.version}</version>
 61         </dependency>
 62         <dependency>
 63             <groupId>org.springframework</groupId>
 64             <artifactId>spring-orm</artifactId>
 65             <version>${org.springframework.version}</version>
 66         </dependency>
 67         <dependency>
 68             <groupId>org.springframework</groupId>
 69             <artifactId>spring-tx</artifactId>
 70             <version>${org.springframework.version}</version>
 71         </dependency>
 72
 73         <!-- Hibernate -->
 74         <dependency>
 75             <groupId>org.hibernate</groupId>
 76             <artifactId>hibernate-core</artifactId>
 77             <version>${org.hibernate.version}</version>
 78         </dependency>
 79
 80         <!-- Log4j -->
 81         <dependency>
 82             <groupId>log4j</groupId>
 83             <artifactId>log4j</artifactId>
 84             <version>${log4j.version}</version>
 85         </dependency>
 86
 87         <!-- MySQL -->
 88         <dependency>
 89             <groupId>mysql</groupId>
 90             <artifactId>mysql-connector-java</artifactId>
 91             <version>5.1.25</version>
 92         </dependency>
 93
 94         <!-- AOP -->
 95         <dependency>
 96             <groupId>aopalliance</groupId>
 97             <artifactId>aopalliance</artifactId>
 98             <version>1.0</version>
 99         </dependency>
100         <dependency>
101             <groupId>org.aspectj</groupId>
102             <artifactId>aspectjweaver</artifactId>
103             <version>1.7.2</version>
104         </dependency>
105
106         <!-- annotation -->
107         <dependency>
108             <groupId>javax.annotation</groupId>
109             <artifactId>jsr250-api</artifactId>
110             <version>1.0</version>
111         </dependency>
112     </dependencies>
113     <build>
114         <finalName>spring-demo</finalName>
115     </build>
116 </project>

Pom.xml

2.编写DAO接口以及实现类

(1)一般我们都会给我们的dao建一个基类,以封装一些通用的方法和sessionFactory。我这里也在网上找了一个别人写好的基类,代码如下:

  1 /**************IGenericDao<T>接口********************/
  2 package com.wzhang.springdemo.dao;
  3
  4 import java.util.List;
  5
  6 public interface IGenericDao<T> {
  7
  8     void insert(T t);
  9
 10     void delete(T t);
 11
 12     void update(T t);
 13
 14     T queryById(String id);
 15
 16     List<T> queryAll();
 17 }
 18
 19 /******************实现类**********************/
 20
 21 package com.wzhang.springdemo.dao;
 22
 23 import java.util.List;
 24
 25 import org.hibernate.Query;
 26 import org.hibernate.SessionFactory;
 27 import org.springframework.beans.factory.annotation.Autowired;
 28
 29 public abstract class GenericDao<T> implements IGenericDao<T> {
 30
 31     private Class<T> entityClass;
 32
 33     public GenericDao(Class<T> clazz) {
 34         this.entityClass = clazz;
 35     }
 36
 37     /**
 38      * 使用注解方式,注入SessionFactory
 39      */
 40     @Autowired
 41     private SessionFactory sessionFactory;
 42
 43     public void insert(T t) {
 44         sessionFactory.getCurrentSession().save(t);
 45     }
 46
 47     public void delete(T t) {
 48         sessionFactory.getCurrentSession().delete(t);
 49     }
 50
 51     public void update(T t) {
 52         sessionFactory.getCurrentSession().update(t);
 53     }
 54
 55
 56     @SuppressWarnings("unchecked")
 57     public T queryById(String id) {
 58         return (T) sessionFactory.getCurrentSession().get(entityClass, id);
 59     }
 60
 61     public List<T> queryAll() {
 62         String hql = "from " + entityClass.getSimpleName();
 63         return queryForList(hql, null);
 64     }
 65
 66     @SuppressWarnings("unchecked")
 67     protected T queryForObject(String hql, Object[] params) {
 68         Query query = sessionFactory.getCurrentSession().createQuery(hql);
 69         setQueryParams(query, params);
 70         return (T) query.uniqueResult();
 71     }
 72
 73     @SuppressWarnings("unchecked")
 74     protected T queryForTopObject(String hql, Object[] params) {
 75         Query query = sessionFactory.getCurrentSession().createQuery(hql);
 76         setQueryParams(query, params);
 77         return (T) query.setFirstResult(0).setMaxResults(1).uniqueResult();
 78     }
 79
 80     @SuppressWarnings("unchecked")
 81     protected List<T> queryForList(String hql, Object[] params) {
 82         Query query = sessionFactory.getCurrentSession().createQuery(hql);
 83         setQueryParams(query, params);
 84         return query.list();
 85     }
 86
 87     /**
 88      *
 89      * @param hql
 90      * @param params
 91      * @param recordNum
 92      * @return
 93      */
 94     @SuppressWarnings("unchecked")
 95     protected List<T> queryForList(final String hql, final Object[] params,
 96             final int recordNum) {
 97         Query query = sessionFactory.getCurrentSession().createQuery(hql);
 98         setQueryParams(query, params);
 99         return query.setFirstResult(0).setMaxResults(recordNum).list();
100     }
101
102     /**
103      *
104      * @param query
105      * @param params
106      */
107     private void setQueryParams(Query query, Object[] params) {
108         if (null == params) {
109             return;
110         }
111         for (int i = 0; i < params.length; i++) {
112             query.setParameter(i, params[i]);
113         }
114     }
115
116 }

IGenericDao

(2)完成CustomerDao和CustomerDaoImpl.代码如下:

 1 /****************接口*******************/
 2
 3 package com.wzhang.springdemo.dao;
 4
 5 import com.wzhang.springdemo.domain.Customer;
 6
 7 /**
 8  * CustomerDao
 9  * @author wzhang
10  *
11  */
12 public interface CustomerDao extends IGenericDao<Customer> {
13     /**
14      * 保存客户
15      * @param cus
16      * @return 成功返回0,失败返回-1
17      */
18     public int saveCustomer(Customer cus);
19 }
20
21
22 /***************实现类****************/
23
24 package com.wzhang.springdemo.dao;
25
26 import org.springframework.stereotype.Service;
27
28 import com.wzhang.springdemo.domain.Customer;
29
30 /**
31  * CustomerDao实现类
32  * @author wzhang
33  *
34  */
35 @Service("customerDao")
36 public class CustomerDaoImpl extends GenericDao<Customer> implements
37         CustomerDao {
38
39     public CustomerDaoImpl() {
40         super(Customer.class);
41     }
42
43     public int saveCustomer(Customer cus) {
44         try {
45             this.insert(cus);
46             return 0;
47         } catch (Exception e) {
48             throw new RuntimeException(e);
49         }
50     }
51
52 }

3.按一般项目惯例,我们这里也搞一个service层,同时事务管理也在service层。

 1 /***************CustomerService接口****************/
 2
 3 package com.wzhang.springdemo.service;
 4
 5 import java.util.List;
 6
 7 import com.wzhang.springdemo.domain.Customer;
 8
 9 /**
10  * CustomerService
11  * @author wzhang
12  *
13  */
14 public interface CustomerService {
15     /**
16      * 批量保存
17      * @param customers
18      * @return
19      */
20     int saveCustomers(List<Customer> customers);
21 }
22
23 /******************实现类***********************/
24
25 package com.wzhang.springdemo.service.impl;
26
27 import java.util.List;
28
29 import javax.annotation.Resource;
30
31 import org.springframework.stereotype.Service;
32
33 import com.wzhang.springdemo.dao.CustomerDao;
34 import com.wzhang.springdemo.domain.Customer;
35 import com.wzhang.springdemo.service.CustomerService;
36
37 @Service("customerService")
38 public class CustomerServiceImpl implements CustomerService {
39
40     /**
41      * 注入dao
42      */
43     @Resource(name = "customerDao")
44     private CustomerDao dao;
45
46     public int saveCustomers(List<Customer> customers) {
47         try {
48             for (Customer cus : customers) {
49                 dao.saveCustomer(cus);
50             }
51         } catch (Exception e) {
52             throw new RuntimeException(e);
53         }
54         return 0;
55     }
56 }

4.配置applicationContext.xml

Spring声明式事务的配置主要有以下几部分内容:

(1)配置数据源dataSource.配置数据源时通常会使用分散配置,将具体的数据库驱动,url等信息配置在一个独立的properties文件中。

   在spring配置文件(applicationContext.xml)中使用<context:property-placeholder location="..." />引入properties资源。

db.properties(路径:/resource/properties/db.properties)

1 jdbc.driverclass=com.mysql.jdbc.Driver
2 jdbc.url=jdbc:mysql://192.168.1.107:3306/test
3 jdbc.username=wzhang
4 jdbc.password=wzhang
5
6 hibernate.dialect=org.hibernate.dialect.HSQLDialect
7 hibernate.show_sql=true
8 hibernate.hbm2ddl.auto=none

applicationContex中dataSource配置:  

 1     <!-- 配置DataSource -->
 2     <bean id="dataSource"
 3         class="org.springframework.jdbc.datasource.DriverManagerDataSource">
 4         <property name="driverClassName">
 5             <value>${jdbc.driverclass}</value>
 6         </property>
 7         <property name="url">
 8             <value>${jdbc.url}</value>
 9         </property>
10         <property name="username">
11             <value>${jdbc.username}</value>
12         </property>
13         <property name="password">
14             <value>${jdbc.password}</value>
15         </property>
16     </bean>

(2)配置会话工厂SessoryFactory.需要注入dataSource.

    <!-- 配置SessoryFactory -->
    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">${hibernate.dialect}</prop>
                <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
                <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
            </props>
        </property>
        <!-- 基于Hibernate注解,扫描给定包 -->
        <property name="packagesToScan" value="com.wzhang.springdemo.domain"></property>

        <!-- 基于*.hbm.xml映射文件  -->
        <!--
        <property name="mappingResources">
        <list>
        <value>com/wzhang/springdemo/domain/customer.hbm.xml</value>
        </list>
        </property>
        -->
    </bean>

  

(3)配置事务管理器TransactionManager.需要注入sessionFactory.

1     <!-- TransactionManager 配置事务管理器 -->
2     <bean id="transactionManager"
3         class="org.springframework.orm.hibernate4.HibernateTransactionManager">
4         <property name="sessionFactory" ref="sessionFactory" />
5     </bean>

(4)配置事务通知(传播行为,隔离级别,只读,超时,回滚规则等).节点<tx:advice></tx:advice>,需要配置spring-tx-3.x相关的scheme。

 1     <!-- 配置事务属性,传播特性,隔离级别 -->
 2     <tx:advice id="txAdvice" transaction-manager="transactionManager">
 3         <!-- 指定具体需要拦截的方法 -->
 4         <tx:attributes>
 5             <!-- 拦截do开头,save开头的方法,事务传播行为是required 隔离级别为default -->
 6             <tx:method name="do*" propagation="REQUIRED" isolation="DEFAULT" />
 7             <tx:method name="save*" propagation="REQUIRED" isolation="DEFAULT" />
 8             <!-- 除上述定义之外的方法,事务属性为只读  -->
 9             <tx:method name="*" read-only="true" />
10         </tx:attributes>
11     </tx:advice>

(5)配置切面(切入点和切入点通知).节点<aop:config></aop:config>.需要配置spring-aop相关的scheme。

1     <!-- 配置切入点 -->
2     <aop:config>
3         <!-- 切入点,拦截*service接口及其实现类 -->
4         <aop:pointcut expression="execution(* com.wzhang.springdemo.service.*Service.*(..))"
5             id="serviceMethod" />
6         <!-- 切入点通知 -->
7         <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethod" />
8     </aop:config>

applicationContext.xml:(路径:/resource/spring/applicationContext.xml)

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
 4     xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
 5     xsi:schemaLocation="http://www.springframework.org/schema/beans
 6     http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
 7     http://www.springframework.org/schema/context
 8     http://www.springframework.org/schema/context/spring-context-3.2.xsd
 9     http://www.springframework.org/schema/tx
10     http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
11     http://www.springframework.org/schema/aop
12     http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
13
14     <!-- 分散配置 -->
15     <context:property-placeholder location="classpath:properties/db.properties" />
16
17     <!-- 扫描包 -->
18     <context:component-scan base-package="com.wzhang" />
19
20     <!-- 激活注解 -->
21     <context:annotation-config />
22
23     <!-- 这是基于注解的方式配置事务 -->
24     <tx:annotation-driven transaction-manager="transactionManager" />
25
26     <!-- 配置DataSource -->
27     <bean id="dataSource"
28         class="org.springframework.jdbc.datasource.DriverManagerDataSource">
29         <property name="driverClassName">
30             <value>${jdbc.driverclass}</value>
31         </property>
32         <property name="url">
33             <value>${jdbc.url}</value>
34         </property>
35         <property name="username">
36             <value>${jdbc.username}</value>
37         </property>
38         <property name="password">
39             <value>${jdbc.password}</value>
40         </property>
41     </bean>
42
43     <!-- 配置SessoryFactory -->
44     <bean id="sessionFactory"
45         class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
46         <property name="dataSource" ref="dataSource" />
47         <property name="hibernateProperties">
48             <props>
49                 <prop key="hibernate.dialect">${hibernate.dialect}</prop>
50                 <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
51                 <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
52             </props>
53         </property>
54         <!-- 基于Hibernate注解,扫描给定包 -->
55         <property name="packagesToScan" value="com.wzhang.springdemo.domain"></property>
56
57
58         <!-- 基于*.hbm.xml映射文件  -->
59         <!--
60         <property name="mappingResources">
61         <list>
62         <value>com/wzhang/springdemo/domain/customer.hbm.xml</value>
63         </list>
64         </property>
65         -->
66     </bean>
67
68     <!-- TransactionManager 配置事务管理器 -->
69     <bean id="transactionManager"
70         class="org.springframework.orm.hibernate4.HibernateTransactionManager">
71         <property name="sessionFactory" ref="sessionFactory" />
72     </bean>
73
74     <!-- 配置事务属性,传播特性,隔离级别 -->
75     <tx:advice id="txAdvice" transaction-manager="transactionManager">
76         <!-- 指定具体需要拦截的方法 -->
77         <tx:attributes>
78             <!-- 拦截do开头,save开头的方法,事务传播行为是required 隔离级别为default -->
79             <tx:method name="do*" propagation="REQUIRED" isolation="DEFAULT" />
80             <tx:method name="save*" propagation="REQUIRED" isolation="DEFAULT" />
81             <!-- 除上述定义之外的方法,事务属性为只读  -->
82             <tx:method name="*" read-only="true" />
83         </tx:attributes>
84     </tx:advice>
85
86     <!-- 配置切入点 -->
87     <aop:config>
88         <!-- 切入点,拦截*service接口及其实现类 -->
89         <aop:pointcut expression="execution(* com.wzhang.springdemo.service.*Service.*(..))"
90             id="serviceMethod" />
91         <!-- 切入点通知 -->
92         <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethod" />
93     </aop:config>
94 </beans>

applicationContext.xml

四、测试

新建测试类HibernateTest.java:

1.测试正常保存情况

测试方法:

 1     @SuppressWarnings("resource")
 2     @Test
 3     public void bathSaveTest() {
 4         ApplicationContext ctx = new ClassPathXmlApplicationContext(
 5                 "classpath:spring/applicationContext.xml");
 6
 7         CustomerService service = (CustomerService) ctx
 8                 .getBean("customerService");
 9         List<Customer> list = new ArrayList<Customer>();
10         for (int i = 0; i < 3; i++) {
11             Customer c = new Customer();
12             c.setAge(10 + i * 10);
13             c.setName("张三");
14             list.add(c);
15         }
16         service.saveCustomers(list);
17     }

bathSaveTest

在mysql中执行:select * from customer,查看结果如下:

说明批量保存没有问题。

2.修改Customer中的name属性,设置name不能为空(nullable=false)。新增测试方法transactionTest(),测试事务是否回滚。

测试方法:

 1     @SuppressWarnings("resource")
 2     @Test
 3     public void transationTest() {
 4         ApplicationContext ctx = new ClassPathXmlApplicationContext(
 5                 "classpath:spring/applicationContext.xml");
 6
 7         CustomerService service = (CustomerService) ctx
 8                 .getBean("customerService");
 9         List<Customer> list = new ArrayList<Customer>();
10         for (int i = 0; i < 3; i++) {
11             Customer c = new Customer();
12             if (i == 2) {//i=2时设置name为空,测试事务是否回滚
13                 c.setAge(10 + i * 10);
14                 c.setName(null);
15             } else {
16                 c.setAge(10 + i * 10);
17                 c.setName("张三");
18             }
19             list.add(c);
20         }
21         service.saveCustomers(list);
22     }

transationTest方法

测试结果:junit测试失败,抛出异常。

在mysql中查看表customer中数据:

可以看出数据库数据并没有插入成功,全部回滚了。

其实我们还需要在service中提供一个单一保存customer的方法,然后在测试类中循环调用,看是否只有name为null的没有保存成功。我这里就不测了。。。^_^

五、总结

本文简单介绍了下spring的声明式事务的使用。

示例代码:spring-transaction.zip

时间: 2024-10-12 23:02:01

JavaEE学习之Spring声明式事务的相关文章

spring学习笔记(22)声明式事务配置,readOnly无效写无异常

在上一节内容中,我们使用了编程式方法来配置事务,这样的优点是我们对每个方法的控制性很强,比如我需要用到什么事务,在什么位置如果出现异常需要回滚等,可以进行非常细粒度的配置.但在实际开发中,我们可能并不需要这样细粒度的配置.另一方面,如果我们的项目很大,service层方法很多,单独为每个方法配置事务也是一件很繁琐的事情.而且也可能会造成大量重复代码的冗杂堆积.面对这些缺点,我们首要想到的就是我们spring中的AOP了.spring声明式事务的实现恰建立在AOP之上. 在这一篇文章中,我们介绍s

Spring声明式事务管理与配置详解

转载:http://www.cnblogs.com/hellojava/archive/2012/11/21/2780694.html 1.Spring声明式事务配置的五种方式 前段时间对Spring的事务配置做了比较深入的研究,在此之前对Spring的事务配置虽说也配置过,但是一直没有一个清楚的认识.通过这次的学习发觉Spring的事务配置只要把思路理清,还是比较好掌握的. 总结如下: Spring配置文件中关于事务配置总是由三个组成部分,分别是DataSource.TransactionMa

Spring声明式事务管理与配置介绍

转至:http://java.9sssd.com/javafw/art/1215 [摘要]本文介绍Spring声明式事务管理与配置,包括Spring声明式事务配置的五种方式.事务的传播属性(Propagation).Spring事务的隔离级别(Isolation level)等内容. 一.Spring声明式事务配置的五种方式 前段时间对Spring的事务配置做了比较深入的研究,在此之间对Spring的事务配置虽说也配置过,但是一直没有一个清楚的认识.通过这次的学习发觉Spring的事务配置只要把

spring声明式事务配置详解

spring声明式事务配置详解 君子不器 2013年06月16日 编程世界 5273次阅读 查看评论 理解Spring的声明式事务管理实现 本节的目的是消除与使用声明式事务管理有关的神秘性.简单点儿总是好的,这份参考文档只是告诉你给你的类加上@Transactional注解,在配置文件中添加('<tx:annotation-driven/>')行,然后期望你理解整个过程是怎么工作的.此节讲述Spring的声明式事务管理内部的工作机制,以帮助你在面对事务相关的问题时不至于误入迷途,回朔到上游平静

Spring声明式事务管理(基于注解方式实现)

----------------------siwuxie095 Spring 声明式事务管理(基于注解方式实现) 以转账为例 1.导入相关 jar 包(共 10 个包) (1)导入核心 jar 包和日志相关的 jar 包 (2)导入 JdbcTemplate 的 jar 包 (3)导入 MySQL 的 JDBC 驱动包 mysql-connector-java 下载链接: https://dev.mysql.com/downloads/connector/j/ (4)导入 AOP 的 jar

spring 声明式事务管理

简单理解事务: 比如你去ATM机取1000块钱,大体有两个步骤:首先输入密码金额,银行卡扣掉1000元钱:然后ATM出1000元钱.这两个步骤必须是要么都执行要么都不执行.如果银行卡扣除了1000块但是ATM出钱失败的话,你将会损失1000元:如果银行卡扣钱失败但是ATM却出了1000块,那么银行将损失1000元.所以,如果一个步骤成功另一个步骤失败对双方都不是好事,如果不管哪一个步骤失败了以后,整个取钱过程都能回滚,也就是完全取消所有操作的话,这对双方都是极好的. 当这两个步骤提交了,执行完毕

spring 声明式事务管理注解方式实现

使用注解实现Spring的声明式事务管理,更加简单! 步骤: 1) 必须引入Aop相关的jar文件 2) bean.xml中指定注解方式实现声明式事务管理以及应用的事务管理器类 3)在需要添加事务控制的地方,写上: @Transactional @Transactional注解: 1)应用事务的注解 2)定义到方法上: 当前方法应用spring的声明式事务 3)定义到类上:   当前类的所有的方法都应用Spring声明式事务管理; 4)定义到父类上: 当执行父类的方法时候应用事务. 案例: 1.

spring声明式事务以及配置

使用spring提供的事务处理机制的好处是程序员可以不用关心事务的切面了,只要配置就好了,可以少写代码. spring声明式事务处理 spring 声明:针对的是程序员,程序员告诉spring容器,哪些方法需要事务,哪些方法不需要事务 事务处理   spring容器来做事务处理 目的:让spring管理事务,开发者不再关注事务 spring声明式事务处理的步骤: 1.搭建环境 2.把dao层和service层的接口和类写完 3.在spring的配置文件中,先导入dataSource 4.测试 5

Spring 声明式事务,propagation属性列表及isolation(隔离级别)

Spring 声明式事务,propagation属性列表 TransactionDefinition接口中定义,共有7种选项可用: PROPAGATION_REQUIRED:支持当前事务,如果当前没有事务,就新建一个事务.这是最常见的选择.PROPAGATION_SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行.PROPAGATION_MANDATORY:支持当前事务,如果当前没有事务,就抛出异常.PROPAGATION_REQUIRES_NEW:新建事务,如果当前存在事务,