Spring的声明式事务顾名思义就是采用声明的方式来处理事务。这里所说的声明,就是指在配置文件中申明。用在Spring配置文件中声明式的处理事务来代替代码式的处理事务。这样的好处是,事务管理不侵入开发的组件,具体来说,业务逻辑对象就不会意识到正在事务管理之中,事实上也应该如此,因为事务管理是属于系统层面的服务,而不是业务逻辑的一部分,如果想要改变事务管理策划的话,也只需要在定义文件中重新配置即可;在不需要事务管理的时候,只要在设定文件上修改一下,即可移去事务管理服务,无需改变代码重新编译,这样维护起来极其方便。



公共类:

package springjdbc;

public interface IUserDao {
	void insertUser(User user);
}



package springjdbc;

public class User {
	private String username;
	private int age;

	public User(String username, int age) {
		this.username = username;
		this.age = age;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

}



xml方式

package springjdbc.transactions.declarative.xml;

import java.sql.Types;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;

import springjdbc.IUserDao;
import springjdbc.User;

public class UserDao implements IUserDao {

	@Autowired
	private JdbcTemplate jdbcTemplate;

	public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
		this.jdbcTemplate = jdbcTemplate;
	}

	public void insertUser(User user) {
		String sql = "insert into tb_user (id, user_name, user_age) values (1, ?, ?)";
		Object[] params = new Object[] { user.getUsername(), user.getAge(), };
		int[] types = new int[] { Types.VARCHAR, Types.INTEGER, };
		jdbcTemplate.update(sql, params, types);
		jdbcTemplate.update(sql, params, types);
	}

}




springjdbc/transactions/declarative/xmlContext.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:context="http://www.springframework.org/schema/context"
	xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
	http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
	http://www.springframework.org/schema/context 
	http://www.springframework.org/schema/context/spring-context-3.0.xsd
	http://www.springframework.org/schema/tx
	http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
	http://www.springframework.org/schema/aop
	http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
	<context:annotation-config />
	
	<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="insert*" propagation="REQUIRED" />
		</tx:attributes>
	</tx:advice>
	<aop:config>
		<aop:pointcut id="userDaoTxPointcut" expression="execution(* springjdbc.IUserDao.*(..))" />
		<aop:advisor advice-ref="txAdvice" pointcut-ref="userDaoTxPointcut" />
	</aop:config>
	 
	<bean id="dataSource"
		class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<property name="url" value="jdbc:oracle:thin:@localhost:1521:ORCL" />
		<property name="username" value="HIBERNATE" />
		<property name="password" value="HIBERNATE" />
		<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
	</bean>
	<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
		<property name="dataSource" ref="dataSource"></property>
	</bean>
	<bean id="userDao" class="springjdbc.transactions.declarative.xml.UserDao">
		<property name="jdbcTemplate" ref="jdbcTemplate"></property>
	</bean>

</beans>




测试类:

package springjdbc.transactions.declarative;

import java.util.Random;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import springjdbc.IUserDao;
import springjdbc.User;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("xmlContext.xml")
public class TestXml {
	
	@Autowired
	ApplicationContext context;
	
	@Test
	public void test() throws Exception {
		Random random = new Random();
		IUserDao dao = context.getBean("userDao", IUserDao.class);
		int id = random.nextInt(100);
		User user = new User("user" + id, id);
		dao.insertUser(user);
	}

}




运行test,会报错,没有插入数据。


annotation方式

package springjdbc.transactions.declarative.annotation;

import java.sql.Types;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.annotation.Transactional;

import springjdbc.IUserDao;
import springjdbc.User;

@Transactional
public class UserDao implements IUserDao {

	@Autowired
	private JdbcTemplate jdbcTemplate;

	public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
		this.jdbcTemplate = jdbcTemplate;
	}

	public void insertUser(User user) {
		String sql = "insert into tb_user (id, user_name, user_age) values (1, ?, ?)";
		Object[] params = new Object[] { user.getUsername(), user.getAge(), };
		int[] types = new int[] { Types.VARCHAR, Types.INTEGER, };
		jdbcTemplate.update(sql, params, types);
		jdbcTemplate.update(sql, params, types);
	}

}




springjdbc/transactions/declarative/annotationContext.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:context="http://www.springframework.org/schema/context"
	xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
	http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
	http://www.springframework.org/schema/context 
	http://www.springframework.org/schema/context/spring-context-3.0.xsd
	http://www.springframework.org/schema/tx
	http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
	http://www.springframework.org/schema/aop
	http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
	<context:annotation-config />
	
	<tx:annotation-driven  transaction-manager="transactionManager"/>
	 
	<bean id="transactionManager"
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource"></property>
	</bean>
	 
	<bean id="dataSource"
		class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<property name="url" value="jdbc:oracle:thin:@localhost:1521:ORCL" />
		<property name="username" value="HIBERNATE" />
		<property name="password" value="HIBERNATE" />
		<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
	</bean>
	<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
		<property name="dataSource" ref="dataSource"></property>
	</bean>
	<bean id="userDao" class="springjdbc.transactions.declarative.annotation.UserDao">
		<property name="jdbcTemplate" ref="jdbcTemplate"></property>
	</bean>

</beans>




测试类:

package springjdbc.transactions.declarative;

import java.util.Random;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import springjdbc.IUserDao;
import springjdbc.User;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("annotationContext.xml")
public class TestAnnotation {
	
	@Autowired
	ApplicationContext context;
	
	@Test
	public void test() throws Exception {
		Random random = new Random();
		IUserDao dao = context.getBean("userDao", IUserDao.class);
		int id = random.nextInt(100);
		User user = new User("user" + id, id);
		dao.insertUser(user);
	}

}




会报错,数据库里没有插入数据。