程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> Spring(九)Spring對事務的支持,spring事務支持

Spring(九)Spring對事務的支持,spring事務支持

編輯:JAVA綜合教程

Spring(九)Spring對事務的支持,spring事務支持


一、對事務的支持

事務:是一組原子操作的工作單元,要麼全部成功,要麼全部失敗

Spring管理事務方式:

  • JDBC編程事務管理:--可以控制到代碼中的行

可以清楚的控制事務的邊界,事務控制粒度化細(編程的方式

  • JDBC聲明事務管理---可以控制到方法

事務相關API不用介入程序之中,將事務管理與實際業務代碼解耦合(配置XML的方式)

 

 

二、JDBC編程事務管理

Spring提供兩種方式實現編程式的事務管理:

  • 實現PlatformTransactionManager接口
  • 使用TransactionTemplate模式

2.1、實現PlatformTransactionManager接口

大致步驟:

  • 指定PlatformTransactionManager的實現類
  • 定義事務TransactionDefinition
  • 將事務定義傳送給TransactionStatus
  • 將欲進行的事務用try..catch語句封起來
  • 如果事務出錯,調用PlatformTransactionManager的rollback方法
復制代碼
package com.pb.transaction.demo;

import javax.sql.DataSource;

import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

/**
 * 使用TransactionManager事務管理
 * 缺點:侵入代碼
 * 優點:控制度細粒度
 */
public class TransactionManagerDemo {
    
    public static void main(String[] args) {
    ClassPathXmlApplicationContext cpx=new ClassPathXmlApplicationContext("applicationContext.xml");    
    //獲取platform對象
    PlatformTransactionManager ptm=(PlatformTransactionManager) cpx.getBean("transactionManager");
    //事務定義器
    DefaultTransactionDefinition dtd=new DefaultTransactionDefinition();
    //設置事務定義器的行為
    dtd.setPropagationBehavior(DefaultTransactionDefinition.PROPAGATION_REQUIRED);
    //事務狀態通過事務管理器創建
    TransactionStatus ts=ptm.getTransaction(dtd);
    
    //進行事務
    
    try {
        //獲取數據源
        DataSource ds=(DataSource) cpx.getBean("dataSource");
        //創建JDBCTemplacte
        JdbcTemplate jt=new JdbcTemplate(ds);
        //執行更新或者插入等操作
        jt.update("insert into person values(11,'TTM',23)");
        jt.update("update person set name='張王八' where id=7");
        ptm.commit(ts);
        
        System.out.println("===========");
    } catch (Exception e) {
        ptm.rollback(ts);
        System.out.println("撤消=======");
        e.printStackTrace();
    }
    
    }

}
復制代碼

 

2.2、使用TransactionTemplate模式

 

大致步驟:

  • 需要封裝一個TransactionManager
  • 創建事務回滾類
  • 執行TransactionManager的execute()方法
復制代碼
package com.pb.transaction.demo;

import javax.sql.DataSource;

import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;

/**
 * 使用TransactionTemplate事務管理 缺點:侵入代碼 優點:控制度細粒度
 */
public class TransactionTeplateDemo {

    public static void main(String[] args) {
        ClassPathXmlApplicationContext cpx = new ClassPathXmlApplicationContext(
                "applicationContext.xml");
        // 獲取platform對象
        PlatformTransactionManager ptm = (PlatformTransactionManager) cpx
                .getBean("transactionManager");
        // 事務模版
        TransactionTemplate tt = new TransactionTemplate(ptm);
        // 獲取數據源
        DataSource ds = (DataSource) cpx.getBean("dataSource");
        // 創建JDBCTemplacte
        final JdbcTemplate jt = new JdbcTemplate(ds);
        // 進行事務回調函數
        tt.execute(new TransactionCallbackWithoutResult() {

            @Override
            protected void doInTransactionWithoutResult(TransactionStatus arg0) {
                // 執行更新或者插入等操作
                jt.update("insert into person values(17,'TOM',23)");
                jt.update("update person set name='李四3' where id=4");


            }
        });

        
    }

}
復制代碼

 

2.3、編程事務配置

復制代碼
<?xml version="1.0" encoding="UTF-8"?>
<beans
    xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">

<!-- 聲明數據源  org.springframework.jdbc.datasource.DriverManagerDataSource/com.mchange.v2.c3p0.ComboPooledDataSource-->                    
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<!--驅動  -->
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
<!--url  -->
<property name="url" value="jdbc:oracle:thin:@localhost:1521:orcl"/>
<!--用戶名  -->
<property name="username" value="accp"/>
<!--密碼  -->
<property name="password" value="accp"/>
</bean>

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
</beans>
復制代碼

 

三、JDBC聲明事務管理

主要通過AOP功能實現

不需要修改原有的類

使用TransationProxyFactoryBean指定要介入的事務以及方法

實體類:數據庫中有與之相對應的表

復制代碼
package com.pb.entity;

public class Person {
    private Long id;
    private String name;
    private Integer age;
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    
    
}
復制代碼

dao和實現類

復制代碼
package com.pb.dao;

import java.util.List;

import com.pb.entity.Person;

public interface PersonDao {

    public int insert(Person p);
    
    public int batchInsert(List<Person> persons);
    
}
//實現類
package com.pb.dao.impl;

import java.util.List;

import javax.sql.DataSource;

import org.springframework.jdbc.core.JdbcTemplate;

import com.pb.dao.PersonDao;
import com.pb.entity.Person;

public class PersonDaoImpl implements PersonDao {
    private JdbcTemplate jdbcTemplate;
    
    public void setDataSource(DataSource ds){
        jdbcTemplate=new JdbcTemplate(ds);
    }
    @Override
    public int insert(Person p) {
        String sql="insert into person values(?,?,?)";
        Object [] params={p.getId(),p.getName(),p.getAge()};
        return jdbcTemplate.update(sql,params);
    }

    @Override
    public int batchInsert(List<Person> persons) {
        int count=0;
        for (Person person : persons) {
            insert(person);
            count++;
        }
        return count;
    }

}
復制代碼

測試類

復制代碼
package com.pb.transation.aop.demo;

import java.util.ArrayList;
import java.util.List;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.pb.dao.PersonDao;
import com.pb.entity.Person;

public class FirstAOPTransationDemo {

    public static void main(String[] args) {
        ClassPathXmlApplicationContext cpx=new ClassPathXmlApplicationContext("applicationContext.xml");    
        //這裡調用代理的類
        PersonDao personDao=(PersonDao) cpx.getBean("personDaoProxy");
        
        Person p1=new Person();
        p1.setId(new Long(28));
        p1.setName("朱雀");
        p1.setAge(199);
        Person p2=new Person();
        p2.setId(new Long(29));
        p2.setName("玄武");
        p2.setAge(150);
        List<Person> persons=new ArrayList<Person>();
        persons.add(p1);
        persons.add(p2);
        int count=personDao.batchInsert(persons);
        System.out.println("更新了,"+count+"條記錄");
        
    }

}
復制代碼

applicationContext.xml配置文件

復制代碼
<?xml version="1.0" encoding="UTF-8"?>
<beans
    xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">

<!-- 聲明數據源  org.springframework.jdbc.datasource.DriverManagerDataSource/com.mchange.v2.c3p0.ComboPooledDataSource-->                    
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<!--驅動  -->
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
<!--url  -->
<property name="url" value="jdbc:oracle:thin:@localhost:1521:orcl"/>
<!--用戶名  -->
<property name="username" value="accp"/>
<!--密碼  -->
<property name="password" value="accp"/>
</bean>
<!--接口實現類  -->
<bean id="personDao" class="com.pb.dao.impl.PersonDaoImpl">
<property name="dataSource" ref="dataSource"></property>
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<bean id="personDaoProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<!--指定接口  -->
<property name="proxyInterfaces" >
<list>
<value>com.pb.dao.PersonDao</value>
</list>
</property>
<!-- 管理的目標 -->
<property name="target" ref="personDao"/>
<!--注入事務管理  -->
<property name="transactionManager" ref="transactionManager"></property>
<!--事務管理的方法 和方式 -->
<property name="transactionAttributes">
<props>
<prop key="batch*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>


</beans>
復制代碼

四、事務的屬性

聲明式事務以方法為邊界,簡單的講,一個方法被看成一個事務

Spring中事務的屬性:

  • 傳播行為(Propagation Behavior)
  • 隔離級別(Lsolation Level)
  • 只讀提示(Rean-only Hints)
  • 事務超時期限(The Transaction Timeout period)

4.1、傳播行為

4.2、隔離級別

 

五、Spring2.0後聲明式事務管理:基於XMLSchema

步驟:

復制代碼
<?xml version="1.0" encoding="UTF-8"?>
<beans
    xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">

<!-- 聲明數據源  org.springframework.jdbc.datasource.DriverManagerDataSource/com.mchange.v2.c3p0.ComboPooledDataSource-->                    
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<!--驅動  -->
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
<!--url  -->
<property name="url" value="jdbc:oracle:thin:@localhost:1521:orcl"/>
<!--用戶名  -->
<property name="username" value="accp"/>
<!--密碼  -->
<property name="password" value="accp"/>
</bean>
<!--接口實現類  -->
<bean id="personDao" class="com.pb.dao.impl.PersonDaoImpl">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--事務管理的類  -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--指明事務管理  -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<!--指定方法和方式  -->
<tx:attributes>
<tx:method name="batch*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<aop:config>
<!--切入點  -->
<aop:pointcut expression="execution(* com.pb.dao.PersonDao.*(..) )" id="mypoint"/>
<!--關切入點和切入對象事務  -->
<aop:advisor advice-ref="txAdvice" pointcut-ref="mypoint"/>
</aop:config>
</beans>
復制代碼

六、基於注解的事務管理

復制代碼
package com.pb.dao.impl;

import java.util.List;

import javax.sql.DataSource;

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.pb.dao.PersonDao;
import com.pb.entity.Person;
//在要管理的類下加上@transactional
@Transactional
public class PersonDaoImpl implements PersonDao {
    private JdbcTemplate jdbcTemplate;
    
    public void setDataSource(DataSource ds){
        jdbcTemplate=new JdbcTemplate(ds);
    }
    @Override
    public int insert(Person p) {
        String sql="insert into person values(?,?,?)";
        Object [] params={p.getId(),p.getName(),p.getAge()};
        return jdbcTemplate.update(sql,params);
    }
    //在要管理的方法下加上屬性propagation=Propagation.REQUIRED
    @Transactional(propagation=Propagation.REQUIRED)
    public int batchInsert(List<Person> persons) {
        int count=0;
        for (Person person : persons) {
            insert(person);
            count++;
        }
        return count;
    }

}
復制代碼

配置文件中加入一條

復制代碼
<?xml version="1.0" encoding="UTF-8"?>
<beans
    xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">

<!-- 聲明數據源  org.springframework.jdbc.datasource.DriverManagerDataSource/com.mchange.v2.c3p0.ComboPooledDataSource-->                    
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<!--驅動  -->
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
<!--url  -->
<property name="url" value="jdbc:oracle:thin:@localhost:1521:orcl"/>
<!--用戶名  -->
<property name="username" value="accp"/>
<!--密碼  -->
<property name="password" value="accp"/>
</bean>
<!--接口實現類  -->
<bean id="personDao" class="com.pb.dao.impl.PersonDaoImpl">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--事務管理的類  -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--指明注解方式的事務管理器  -->
<tx:annotation-driven transaction-manager="transactionManager"/>


</beans>
復制代碼

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved