事務:是一組原子操作的工作單元,要么全部成功,要么全部失敗
Spring管理事務方式:
可以清楚的控制事務的邊界,事務控制粒度化細(編程的方式)
事務相關API不用介入程序之中,將事務管理與實際業務代碼解耦合(配置xml的方式)
二、JDBC編程事務管理Spring提供兩種方式實現編程式的事務管理:

大致步驟:
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模式

大致步驟:
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中事務的屬性:



步驟:
<?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@Transactionalpublic 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>
新聞熱點
疑難解答